wait 和notify


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进行唤醒;