首先,如果在未持有对象锁的情况下调用object.wait()/notify(),直接会报错,JDK已经做好保护。
其次,为什么要这么设计?其实这是一种安全设计,为了防止wait错过notify。请看下面代码:
boolean wakeuped = false;
void dowait()
{
if(wakeuped)
return;
wait();
}
void wakeup()
{
wakeuped = true;
notify();
}
如果一个线程 执行dowait,另一个线程执行wakeup,在没有同步保护的情况下可能存在着这样的执行循序:
[wait thread ] if(wakeuped) return;//wakeuped is false;
[notify thread] wakeuped=true;// wakeuped is true
[notify thread] notify();//此时wait线程没有进入wait,
[wait thread ] wait();//wakuped is true,此时进入wait,而notify先于wait执行,此时wait将不会被唤醒。
在dowait和wakeup两个方法上加上同步锁保护,则可以保证不会出现上面的执行顺序。wakeup要么先于dowait执行,要么在dowait线程进入wait后才能执行。这样通过互斥锁来保证wait()/notify()之间的先后顺序,才能保证wait不会错过notify,从而导致wait线程一直挂着。
博客围绕Java多线程中object.wait()/notify()展开。指出未持有对象锁调用会报错,这是一种安全设计,目的是防止wait错过notify。通过代码示例说明,在无同步保护时执行顺序可能混乱,加同步锁可保证先后顺序,避免wait线程一直挂起。
9058

被折叠的 条评论
为什么被折叠?



