wait 使你可以等待某个条件发生变化,而改变这个条件超出了当前方法的控制能力,通常,这种条件将由另一个任务来改变。你肯定不想在你的任务测试这个条件的同时,不断的进行空循环,这被称为忙等待,通常是一种不良的cpu周期使用方式。因此wait等待会在等待时将任务挂起,并且只有在notify或者notifyAll的时候才会会被唤醒并检查所发生的变化,因此,wait提供了一种在任务之间同步的方法。
调用sleep方法的时候,锁并没有被释放,调用yied()也时一样。而wait将释放掉这个锁。这一点很重要,其他需要这个锁的 互斥区可以被访问。
wait()与notify()属于Object,看起来有些奇怪,不过这是由道理的,因为这些方法操作的锁也时这个对象的一部分,所以,你可以把wait方法放进任何同步方法中,实际上,也只能在同步方法中调用wait,因为要操作锁,当你在非同步中使用wait()的时候,程序能够通过编译,但是在运行的时候经常出错。
让我们看一个简单的示例(我觉得不简单),car 代表一辆车,需要对它涂蜡 和 抛光,但是这两个程序是由步骤的,肯定是先涂蜡,在抛光,然后在涂蜡,这样子,不能没腊也抛光,有腊还继续涂蜡,下面是示例:
class Car{//是否有腊private boolean waxOn = false;//打蜡,有腊,其他任务可以继续public synchronized void waxed(){waxOn = true;//唤醒所有线程,检查状态,该干什么notifyAll();}//抛光,没有腊,其他任务可以继续public synchronized void buffed(){waxOn = false;//唤醒所有线程,检查状态,该干什么notifyAll();}/***如果没有腊,此线程挂起** @throws InterruptedException*/public synchronized void waitForWaxing() throws InterruptedException{while(waxOn == false)wait();}/**** 有腊挂起** @throws InterruptedException*/public synchronized void waitForBuffing() throws InterruptedException{while(waxOn == true)wait();}}class WaxOn implements Runnable {private Car car;public WaxOn(Car c){car = c;}@Overridepublic void run() {try {while(!Thread.interrupted()) {//睡眠,更快退出线程TimeUnit.MILLISECONDS.sleep(200);//打蜡说明System.out.println("Wax On!");//打蜡car.waxed();//根据状态挂起此线程,释放锁,等待唤醒car.waitForBuffing();}} catch (InterruptedException e) {System.out.println("Exiting via interrupt");}System.out.println("Ending Wax On task");}}class WaxOff implements Runnable {private Car car;public WaxOff(Car c){car = c;}@Overridepublic void run() {try {while(!Thread.interrupted()) {//如果没有腊,此线程挂起,释放锁,直到被唤醒car.waitForWaxing();//被唤醒,并且打上了腊//抛光System.out.println("Wax Off");//睡眠,更快退出线程TimeUnit.MILLISECONDS.sleep(200);//汽车状态切换car.buffed();}} catch (InterruptedException e) {System.out.println("Exiting via interrupt");}System.out.println("Ending Wax Off task");}}public class WaxOMatic {public static void main(String[] args) throws Exception{Car car = new Car();ExecutorService exec = Executors.newCachedThreadPool();exec.execute(new WaxOff(car));exec.execute(new WaxOn(car));TimeUnit.SECONDS.sleep(5);exec.shutdownNow();}}Wax On!Wax OffWax On!Wax OffWax On!Wax OffExiting via interruptExiting via interruptEnding Wax Off taskEnding Wax On task
结果只展示了最重要的一部分,在本例中,有两条线程,一条打蜡,一条抛光,因为是先打蜡,所以,可以等打完腊,等待状态改变被唤醒,而打完腊的时候,就会通知所有线程检查状态,做点对应的什么事情,在检查状态是否将本线程挂起,释放锁,
抛光其实也一样,只是抛光是在后面,所以必须要先检查状态,在决定是否抛光,这样,就能够控制到同步的效果
如果觉得《Thinking in java 第21章 并发 wait() 与 notifyAll()》对你有帮助,请点赞、收藏,并留下你的观点哦!