java 等待,通知机制
下面先介绍下Object class 中的method。
void wait():等待条件的发生,该method必须从synchronized method或块中调用。
void wait(long timeout):等待条件的发生,假如,没有在timeout指定的毫秒内发生条件,那么时间到了,还是假定条件已经发生了。
void wait(long timeout,int nanos):与上相似。
void notify():通知正在等待的thread此条件已经发生,这个method必须从synchronized method或块中调用。
接下来先看一段代码:
public synchronized void run(){
while(true){
try{
if(done){
wait();
}else{
repaint();
wait(100);
}
} catch(InterruptedException e){
return;
}
}
}
public synchronized void setDone(boolean b){
done = b;
if(timer == null){
timer = new Thread(this);
timer.start();
}
if(!done){
notify();
}
}
分析:1,调用wait()方法必须具备该对象锁才能调用该方法,同时调用了该方法会释放锁。
2,若收到通知的时候,那么就能再次获得该对象锁。
它跟sleep()的差别相当明显,sleep()不要求具有对象锁,同时不会释放锁。也跟唤醒没有关系。反正,我觉得它们压根就没有关系。
另外,假如没有wait()方法被调用,但是却执行了notify(),那么不会出现错误,就把这信息遗忘掉而已。
常识:1,在wait()方法释放与重新取得lock的期间,绝对不存在race condition。
2,但是许多thread在等待与发送通知,当多个thread在等待通知时会存在race condition。也就是说,假定处理数据的thread被当做一个消费者,它要消耗由其他thread生产的数据。当消费者醒来的时候,它不能假定它锁等待的状态是否还是有效的,它可能在过去是有效的,但状态可能在notify()方法被调用后与消费者被唤醒前产生变化。所以等待的thread必须提供选项以检查状态。
当多个thread在等待通知时,哪个thread会在调用notify()的收到通知时没有办法确定的。因此提供了notifyAll() 方法。
voidnotifyAll():通知所有等待该对象的thread条件已经发生,这个method必须从synchronized method或块中调用。
分析:1,所有等待中的thread被唤醒后,它们都要重新取得对象的lock,它们都必须等待对象的lock被释放掉。
2,notify()可能会通知唤醒在等待完全不一样条件的thread。通过唤醒所有的thread,我们就可以将程序设计成由thread自行决定接下来应该执行哪一个thread。
条件变量:
暂时没有接触到,略。