多个线程不能同时进入同步块吗?

abh*_*aug 2 java multithreading synchronized locks

我是 Java 新手,在了解 Java 中的多线程时遇到了这个链接:http: //tutorials.jenkov.com/java-concurrency/slipped-conditions.html 。

在本教程中,以下代码被称为避免出现滑倒情况的良好实践:

public class Lock {

    private boolean isLocked = true;

    public void lock(){
      synchronized(this){
        while(isLocked){
          try{
            this.wait();
          } catch(InterruptedException e){
            //do nothing, keep waiting
          }
        }
        isLocked = true;
      }
    }

    public synchronized void unlock(){
      isLocked = false;
      this.notify();
    }

}
Run Code Online (Sandbox Code Playgroud)

我的疑问是,如果两个线程 A 和 B 同时调用 lock() 并且 isLocked 为 true,即锁已被其他线程 C 占用。现在:

--1 A 首先进入同步块(因为只有一个人可以获得监视对象 this 的锁并进入同步块) --2 A 调用 this.wait() 并释放监视对象 this 的锁(wait() 调用)释放监视器对象上的锁http://tutorials.jenkov.com/java-concurrency/thread-signaling.html#wait-notify)但仍保留在同步块内 --3 现在 B 进入同步块(因为 A 已释放锁)在监视器对象上 this) --4 B 调用 this.wait() 并因此释放监视器对象 this 上的锁(wait() 调用释放监视器对象上的锁) --5 此时线程 C 调用unlock() ie 将 isLocked 设置为 false 并调用 this.notify() --6 现在 A 和 B 之一出来 wait(),然后从 while 循环中出来并将 isLocked 设置为 true --7 继续循环

那么--3中,A和B同时在一个synchronized块内,这是否违反了synchronized块内一次只能有一个线程的多线程基本原则?

请澄清我的疑问。

JB *_*zet 5

仅当线程重新获取其正在等待的对象上的锁时,该线程才能从 wait() 方法返回。在您的场景中,A 和 B 会竞争获取锁,只有其中一个会获得锁,而另一个会一直等待,直到锁再次释放。

来自javadoc(强调我的):

当前线程必须拥有该对象的监视器。该线程释放此监视器的所有权并等待,直到另一个线程通过调用notify 方法或notifyAll 方法通知在此对象的监视器上等待的线程唤醒。然后,线程等待,直到它可以重新获得监视器的所有权并恢复执行。