Chapter 21 - Exercise 23

(7) Demonstrate that WaxOMatic.java works successfully when you use notify( ) instead of notifyAll( ).


下面的程序,就算是好几个WaxOn任务和WaxOff任务一起跑,也会正常上蜡,除蜡循环操作。

使用notify()替代notifyAll()的关键在于既然不能控制被唤醒的是不是恰当的任务,一个任务收到唤醒信号后,需要判断是不是符合醒来的条件,否则继续等待。而且,继续睡或者完成任务之前,还需要把接力棒传下去唤醒另一个任务,虽然它也不清楚唤醒的是哪个任务。

Car.java



package com.ciaoshen.thinkinjava.chapter21;
import java.util.concurrent.*;
import java.util.*;

public class Car {
    private boolean waxOn = false;
    public synchronized void wax() throws InterruptedException {
        waitForBuffing();
        System.out.print("Wax On! ");
        TimeUnit.MILLISECONDS.sleep(200);
        waxOn = true; // Ready to buff
    }
    public synchronized void buff() throws InterruptedException {
        waitForWaxing();
        System.out.print("Wax Off! ");
        TimeUnit.MILLISECONDS.sleep(200);
        waxOn = false; // Ready to wax
    }
    public synchronized void waitForWaxing() throws InterruptedException {
        while(waxOn == false){
            notify();
            wait();
        }
    }
    public synchronized void waitForBuffing() throws InterruptedException {
        while(waxOn == true){
            notify();
            wait();
        }
    }
}


WaxOn.java



package com.ciaoshen.thinkinjava.chapter21;
import java.util.concurrent.*;

public class WaxOn implements Runnable {
    private Car car;
    public WaxOn(Car c) { car = c; }
    public void run() {
        try {
            while(!Thread.interrupted()) {
                car.wax();
            }
        } catch(InterruptedException e) {
            System.out.println("Exiting via interrupt");
        }
        System.out.println("Ending Wax On task");
    }
}


WaxOff.java



package com.ciaoshen.thinkinjava.chapter21;
import java.util.concurrent.*;

public class WaxOff implements Runnable {
    private Car car;
    public WaxOff(Car c) { car = c; }
    public void run() {
        try {
            while(!Thread.interrupted()) {
                car.buff();
            }
        } catch(InterruptedException e) {
            System.out.println("Exiting via interrupt");
        }
        System.out.println("Ending Wax Off task");
    }
}


Exercise23.java



package com.ciaoshen.thinkinjava.chapter21;
import java.util.concurrent.*;

public class Exercise23 {
    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));
        exec.execute(new WaxOff(car));
        exec.execute(new WaxOn(car));
        exec.execute(new WaxOff(car));
        exec.execute(new WaxOn(car));
        exec.execute(new WaxOff(car));
        exec.execute(new WaxOn(car));
        TimeUnit.SECONDS.sleep(5); // Run for a while...
        exec.shutdownNow(); // Interrupt all tasks
    }
}



Need Java Developers? Hire Me »

I know Java. Talk is cheap, watch my code.

I live in CANADA now.