JAVA方法中的相互线程排除

时间:2015-01-23 12:21:25

标签: java multithreading thread-safety

我需要提供对类方法的相互访问,因此一个线程一次可以执行方法内的代码。 我已经尝试了下面的解决方案,但我无法理解为什么每次变量'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的值发生了变化,但不幸的是它没有发生。 因此,作为最终结果,所有线程都能够执行此方法而没有任何线程安全性。 有没有人知道如何每次为一个线程提供对此方法的独占访问权?

2 个答案:

答案 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/