我希望知道在synchronized块中写入的代码但是在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();
}
}
请帮我澄清我的疑问。
此致 克里希纳
答案 0 :(得分:5)
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 线程然后等待,直到它可以重新获得监视器的所有权并继续执行。
是的,它会锁定。
答案 1 :(得分:4)
对于成功调用对象的wait()
方法的线程,它必须拥有该对象的监视器,并且在{{1}执行期间放弃监视器}}。但是,在从wait()
返回之前,线程重新获取监视器也是如此。你不需要做任何特别的事情来实现这一目标。
也许你对于执行wait()
的线程在停止等待后可能需要与其他人竞争的事实感到困惑,但你不必担心;它发生在wait()
返回之前。同步块的完整性保持不变:始终可以确保在其中执行的代码没有其他线程保存同步对象的监视器,包括在执行wait()
之后。
答案 2 :(得分:3)
根据Javadoc:
线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。
所以,是的,当wait
调用返回时,该线程将拥有监视器,这意味着它以同步的方式运行"" (在当前线程离开sharedObj
块之前,没有其他线程能够执行该代码块或使用相同synchronized
同步的任何其他代码块。)
顺便说一下,同样根据Javadoc,wait
应始终在循环中调用,因为等待可能因某些其他原因而中断,而不是您正在等待的notify
。
例如:
public void process(){
synchronized(sharedObj){
while(!sharedObj.valueCanBeWritten()) {
try{
sharedObj.wait();
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
sharedObj.writeValue();
}
}