为什么wait()要放在同步块中?

现象:不在同步块中,抛出异常:java.lang.IllegalMonitorStateException

Lost Wake-Up Problem(所有多线程环境下都可能会出现)

//生产者伪代码
count+1;
notify();

//消费者伪代码
while(count<=0){
    wait();
}
count--;

分析:count=0,消费者线程进入while(),还没来得及睡觉,发生了上下文切换:生产者线程进来了,count+1,发出通知,唤醒一个线程(这个通知会被丢掉,因为毫无作用),然后消费者线程就睡过去了。。。

问题的根源:消费者线程检查count到调用wait之间,count有可能被改掉了。(竞态条件)

解决方案:让生产者和消费者竞争同一把锁,竞争到了才能够修改count的值。

Java强制wait()/notify()必须在同一个代码块,且是锁对象的同步块中。还有(java.util.concurrent.locks.Condition的await()/signal()也必须在同步块中)

面试官提问,第一次回答:这是Java设计者为了避免使用者出现Lost Wake-Up Problem问题而搞出来的。

面试官追问:Lost Wake-Up Problem问题是什么?

然后再回答上面的内容。。

 

 

你可能感兴趣的:(JavaSE)