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

bqf10yzr  于 2022-10-01  发布在  Java
关注(0)|答案(2)|浏览(174)

我是新接触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();
    }

}

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

--1 A首先进入同步块(因为只有一个人可以获得对监视器对象http://tutorials.jenkov.com/java-concurrency/thread-signaling.html#wait-notify)的锁定并进入同步块)--2 A调用这个.Wait(),因此释放对监视器对象的锁定。这个(Wait()调用释放对监视器对象Wait的锁定,但保持在同步块内-3现在B进入同步块(因为A已经释放了对监视对象的锁定)--4 B调用这个。Wait(),依此类推释放监视器对象上的锁这个(Wait()调用释放监视器对象上的锁)--5此时线程C调用unlock(),即将isLocked设置为False并调用this.tify()--6现在A和B中的一个出来等待(),然后从While循环中退出,并将isLocked设置为真--7,循环继续

因此,在--3中,A和B同时位于一个同步块中,这是否违反了一个同步块中一次只允许一个线程的基本多线程原则?

请澄清我的疑问。

dxpyg8gm

dxpyg8gm1#

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

来自javadoc(重点是我的):
当前线程必须拥有此对象的监视器。该线程释放该监视器的所有权并等待,直到另一个线程通过调用Notify方法或NotifyAll方法通知等待该对象的监视器的线程唤醒。线程然后等待,直到它可以重新获得监视器的所有权并恢复执行。

gfttwv5a

gfttwv5a2#

我也有同样的问题,@随机性编译器。

一旦可能有多个线程进入受同一对象监视器锁保护的同步块(或方法),则关键字同步的目的就失效了(例如。代码块中可以有多个线程修改共享数据,尽管只有一个线程占用了CPU)。

相关问题