我需要提供对类方法的相互访问,因此一个线程一次可以执行方法内的代码。 我已经尝试了下面的解决方案,但我无法理解为什么每次变量'locked'的值都是假的。
public class MyCommand extends BaseCommand {
private static boolean locked=false;
@Override
public boolean execute() throws Exception {
synchronized(MyCommand.class){
while (locked){
wait();
}
locked=true;
//some code with a breakpoint/long blocking operations
locked=false;
notifyAll();
return true;
}
}
我在开头的while语句中放置了一个断点,并且lock变量的值总是为false,我无法理解为什么。 第二个断点位于方法的主体中,我使用它来阻止第一个线程的执行,并看到第二个线程中变量lock的值发生了变化,但不幸的是它没有发生。 因此,作为最终结果,所有线程都能够执行此方法而没有任何线程安全性。 有没有人知道如何每次为一个线程提供对此方法的独占访问权?
答案 0 :(得分:3)
同步块中一次只有一个线程,对吧?
您在块的开头停止线程,并检查locked
的值。好吧,如果你的线程在块内,这意味着没有其他线程。如果里面没有其他线程,那么locked
必须是假的,这就是重点。为什么会让你感到惊讶?
顺便说一句,你不需要while(locked) wait()
循环(或整个locked
事物)完全由于上述原因 - 整个“锁定”是通过{ {1}}锁定您的代码。
答案 1 :(得分:1)
值始终为false,因为一次只有一个线程正在执行synchronized块,所以......当第一个线程完成变量时,该值再次为false ...然后,下一个线程读取为false。
在这种情况下,我更喜欢使用ReentrantLock,例如:
protected final ReentrantLock myLock= new ReentrantLock();
...
try {
//wait until i have the lock
this.myLock.lock();
//do some stuff
} finally {
//release the lock
this.myLock.unlock();
}
在本文中,您可以看到synch部分和ReentrantLock之间的性能差异很大: http://lycog.com/concurency/performance-reentrantlock-synchronized/