1.锁机制可以很好的解决线程之间资源的竞争访问,通过wait和notify实现线程间的握手合作
wait:调用sleep方法锁并没有施放,调用yield也是同样的情况。当一个任务在方法里遇到了对wait的调用的时候,线程的执行被挂起,对象上的锁被施放,这意味着另外的一个任务可以获取这个锁,因此该对象的其他shnchronized方法可以在wait期间被调用,这一点很重要,因为这些其他的方法通常将会产生改变,而这种改变正是使刚被挂起的任务所感兴趣的变化。
wait()和notify()
和sleep相比,wait方法期间对象锁是施放的,可以通过notify或notifyAll或时间到从wait中恢复执行
public class Car {
private boolean waxOn=false;
public synchronized void waxed(){
waxOn=true;
notifyAll();
}
public synchronized void buffed(){
waxOn=false;
notifyAll();
}
public synchronized void waitForWaxing() throws InterruptedException {
while (waxOn==false){
wait();
}
}
public synchronized void waitForBuffing() throws InterruptedException {
while (waxOn==true){
wait();
}
}
}
必须用一个检查感兴趣的条件while循环包围wait(),很重要:
1.你可能有多个任务出于相同的原因在等待同一个锁,第一个被唤醒任务可能会改变这种状况(本身类没这么做,通过继承你的类去这么做)。如果属于这种情况,那么这个任务应该再次被挂起,直到其感兴趣的条件发生
2.在这个任务从其wait中被唤起的时刻,有可能会有某个其他的任务已经做出了改变,从而使得这个任务在此时不能执行或者执行操作无关紧要,应该再次被挂起
3.也有可能任务出于不同的原因在等对象上的锁,这种情况下,应该检查是否被唤醒的正确原因
其本质就是检查所感兴趣的特定条件,并在条件不满足的时候再次回到wait中,习惯的方法就是使用while来编写这种代码