JAVA 方法中的相互线程排斥

Mutual thread exclusion in a JAVA method

我需要提供一个class方法的相互访问,这样一个线程就可以同时执行方法里面的代码。 我尝试了下面的解决方案,但我不明白为什么每次变量 '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语句开头打了个断点,locked变量的值总是false,我不明白为什么。 第二个断点在方法的主体中,我使用它来阻止第一个线程的执行,并查看第二个线程中锁定变量的值发生了变化,但不幸的是它没有发生。 因此,作为最终结果,所有线程都能够在没有任何线程安全的情况下执行此方法。 有没有人知道我如何每次一个线程提供对该方法的独占访问?

一次只有一个线程在同步块中,对吧? 您在块的开头停止您的线程,并检查 locked 的值。好吧,如果你的线程在块内,那就意味着没有其他线程在。如果没有其他线程在里面,那么 locked 必须是假的,这就是重点。为什么让您感到惊讶?

顺便说一下,您不需要 while(locked) wait() 循环(或整个 locked 循环),正是出于上述原因 - 整个 "locking" 已实现通过 synchronized 锁定您的代码。

该值始终为 false,因为一次只有一个线程在执行同步块,所以...当第一个线程完成时变量再次为 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();
    }

并且在本文中您可以看到同步部分和 ReentrantLock 在性能上的巨大差异: http://lycog.com/concurency/performance-reentrantlock-synchronized/