代码在同步块内但在 wait() 之后以同步方式运行吗?

Do code inside a synchronized block but after wait() runs in synchronized way?

我想知道在同步块中编写的代码,但是在 wait() 语句实际上以同步方式运行之后或不是在 wait() 期间锁定被放弃并且一旦线程被通知它再次需要锁定。

public void process(){
    synchronized(sharedObj){
        try{
             sharedObj.wait();
        }catch(InterruptedException ex){
              ex.printStackTrace();
        }
        // when wait is over do the line below runs in synchronized way. It is inside synchronized block but during call of wait(), lock was relinquished. 
        sharedObj.writeValue();
    }
}

请帮我解惑。

此致, 奎师那

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()

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.

是的,它取回了锁。

确实,要使线程成功调用对象的 wait() 方法,它必须持有该对象的监视器,并且在执行 wait() 期间放弃监视器。然而,线程在从 wait() 返回之前重新获取监视器 也是真实的。你不需要做任何特别的事情来实现它。

也许你对执行wait()的线程在停止等待后可能需要与其他线程竞争监视器感到困惑,但你不必担心;它发生在 wait() returns 之前。同步块的完整性保持不变:始终可以确保在其中执行的代码没有其他线程持有同步对象的监视器,包括在执行 wait() 之后。

根据 Javadoc:

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.

所以,是的,当 wait 调用 returns 时,该线程将拥有监视器,这意味着它是 运行 "in synchronized way"(没有其他线程会能够在当前线程离开 synchronized 块之前执行该代码块或使用相同 sharedObj 同步的任何其他代码块。

顺便说一下,同样根据 Javadoc,wait 应该始终在循环中调用,因为等待可能会因其他原因而中断,而不是您正在等待的 notify对于.

例如:

public void process(){
    synchronized(sharedObj){
        while(!sharedObj.valueCanBeWritten()) {
            try{
                sharedObj.wait();
            }catch(InterruptedException ex){
              ex.printStackTrace();
            }
        }
        sharedObj.writeValue();
    }
}