java - 多个线程不能同时进入同步块(synchronized block)吗?

标签 java multithreading synchronized locks

我是 Java 新手,发现了此链接:http://tutorials.jenkov.com/java-concurrency/slipped-conditions.html同时了解java中的多线程。

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

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();
    }

}

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

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

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

请澄清我的疑问。

最佳答案

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

来自the javadoc (强调我的):

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

关于java - 多个线程不能同时进入同步块(synchronized block)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27764392/

相关文章:

java - private int 在设置后不保留其值

c# - 这是使用 System.Threading.Timer 运行计划的异步/等待方法的正确方法吗?

java - 同步 arrayList- 不兼容的类型

java - LinkedBlockingQueue 中 put() 的性能

java - 奇怪的 HashMap 计数器行为

android - 使用线程从服务中返回START_STICKY

java:同步方法效率低下

java - 基于声明为 "final static Object"的对象与简单的 "final Object"进行同步

java - MariaDb10 (MySQL 5.6) - 从 MySQL 5.5 更新后出现随机高 I/O 和慢查询

java - 帮忙看看下面的代码,是线程安全的吗?