wait 和notify
- wait模板
synchronized(someObject){
while(保护条件不成立)(
someObject.wait();
)
doAction;
}
注意:
保护条件需要循环判断,防止在获取锁的时候,保护条件又不成立,内部锁支持非公平调度,可能有插队将保护条件给修改了,这是需要让线程重新等待。
- notify模板
synchronized(someObject){
updateShareState();
someObject.notify();
}
注意:
notify()需要尽可能放在临界区的结束的地方,否则被唤醒线程可能拿不到锁,导致上下文切换,应该是从waitset进入到entryset等待。
- 开销和问题
Notifyall()过早唤醒,保护条件还没有成立就被唤醒,可以利用显示锁的Condition接口来解决,实现分组唤醒;
信号丢失和欺骗性唤醒通过模板编程即可;
存在上下文切换; - notify()和notifyall()
只有在特定条件下采用notify(),否则都用notifyall():
条件1:一次通知只唤醒一个线程;条件2:线程同质
wait()和sleep()的区别
- 这两个方法来自不同的类,sleep()是Thread的静态方法,wait()是Object的实例方法;
- sleep方法没有释放锁,而wait方法释放了锁;
- wait,notify和notifyAll的调用需要放在同一个对象所引导的临界区中,而sleep可以在任何地方使用;
- sleep到时间会自动恢复。wait必须使用notify或者是notifyall进行唤醒;