为什么在Java中object.wait()/notify()方法必须在持有锁的情况下才能执行?

为什么必须只有锁?我说的是为什么这么设计,不是说这样用的话就会抛异常。。 :o

只有两个线程抢一个资源的时候才存在两个线程同一时刻只能有一个线程得到资源,锁就是为了使两个线程抢同一个资源,如果没有锁,意思是两个线程不存在抢资源情况,那两个线程凭什么你等我 我等你,早就一起跑了。

wait 必需持有锁是一种安全设计,为了防止wait错过notify.请看下面代码。
[code="java"]
boolean wakeuped = false;
void dowait()
{
if(wakeuped)
return;
wait();
}
void wakeup()
{
wakeuped = true;
notify();
}
[/code]
如果一个线程 执行dowait,另一个线程执行wakeup,在没有同步保护的情况下可能存在着这样的执行循序:
[code="java"]
[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将不会被唤醒。
[/code]
在dowait和wakeup两个方法上加上同步锁保护,则可以保证不会出现上面的执行顺序。wakeup要么先于dowait执行,要么在dowait线程进入wait后才能执行。

补充一下,wait逻辑通常是两步操作: (1)先判断特定的条件是否满足,如果不满足,(2)则进入wait。如果没有同步保护,就可能设置条件+唤醒的操作插入在这两步操作中间执行(1和2中间),造成wait线程即错过满足的条件,又因为notify先于wait执行而不会被唤醒。