作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个名为 processOutbox 的方法。我希望它是线程安全的。我不希望另一个线程在一个线程运行时调用此方法。我已经通过以下方式实现了它。我做对了吗?我的实现有没有漏洞?如果有任何问题,请告诉我如何解决它。
this.start();
outboxLock.lock();
timer = new Timer();
try{
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
processOutbox();
}
}, 0, period);
} finally{
outboxLock.unlock();
}
最佳答案
如果你想让你的方法processOutbox,你应该使用关键字synchronized
:
public class YourClass{
public synchronized void processOutbox(){
//do all you want
}
}
更多信息请访问:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
如果在您的代码中有一个 YourClass 的实例,例如 myInstance
,所有对 processOutbox()
的调用都将是线程安全的,因为它们将被锁定在实例级别.
例如:
YourClass myInstance = new YourClass();
Thread thread1 = new Thread(){
public void run(){
myInstance.processOutbox();
}
}
Thread thread2 = new Thread(){
public void run(){
myInstance.processOutbox();
}
}
thread1.start();
thread2.start();
这里 thead2 将等待直到 thread1 完成对“processOutbox”的调用
但是例如:
YourClass myInstance = new YourClass();
YourClass myInstance2= new YourClass();
Thread thread1 = new Thread(){
@Override
public void run(){
myInstance.processOutbox();
}
};
Thread thread2 = new Thread(){
@Override
public void run(){
myInstance2.processOutbox();
}
}
thread1.start();
thread2.start();
thead2 将不等待,因为他们在不同的实例上调用该方法。
有人特别询问有关使用 ReentrantLock 的问题——因此我将此回复添加到此回复中,因为此回复是正确的。
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
outboxLock.lock()
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
我特别提到这一点是因为您还可以做一些事情,在这种情况下,您可以通过使用 tryLock 来避免其他线程被锁定而不会导致它们阻塞。
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
if( outboxLock.tryLock() ) {
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
}
关于java - 在以下上下文中如何确保线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32710303/
我是一名优秀的程序员,十分优秀!