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

时间:2015-01-04 10:03:20

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

}

我怀疑是两个线程A& B同时调用lock()并且isLocked为true,即其他一些线程C已经锁定了。现在:

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

所以在-3中,A和B同时在同步块内,是不是违反了基本的多线程原则,一次只允许在同步块内有一个线程?

请澄清我的疑问。

1 个答案:

答案 0 :(得分:4)

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

来自the javadoc(强调我的):

  

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