0

I try repeat example from Bruce Eckel's book "thinking in java":

    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)
                wait();
        }

        public synchronized void waitForBuffing() throws InterruptedException {
            while (waxOn)
                wait();
        }
    }

public class WaxOff implements Runnable {
    private Car car;

    public WaxOff(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("wax off!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.buffed();
                car.waitForWaxing();
            }
        } catch (InterruptedException e) {
            System.out.println("Exit via interrupt");
        }
        System.out.println("Ending Wax Off task");
    }
}

public class WaxOn implements Runnable {
    private Car car;

    public WaxOn(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("wax on!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.waxed();
                car.waitForBuffing();
            }
        } catch (InterruptedException e) {
            System.out.println("Exit via interrupt");
        }
        System.out.println("Ending Wax On task");
    }
}

public class WaxOMatic {
    public static void main(String[] args) throws Exception {
        Car car = new Car();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new WaxOff(car));
        executorService.execute(new WaxOn(car));
        TimeUnit.SECONDS.sleep(5);
        executorService.shutdown();
    }
}

But I have incorrect behavior of ExecutorService. When I call shutdown method threads not interrupt and contionue work.

But if I change this exampe and use

Future<?> submit = executorService.submit(new WaxOff(car));

And after delay call submit.cancel(true) - Thread is interrupt fine.

It seems that when you call shutdown executor must interrupt all threads and I must go to catch block(catch InterruptedException) but it not work.

xingbin
  • 27,410
  • 9
  • 53
  • 103
ip696
  • 6,574
  • 12
  • 65
  • 128

1 Answers1

3

Executors.newCachedThreadPool use ThreadPoolExecutor internally as thread pool.

ThreadPoolExecutor.shutdown:

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

ThreadPoolExecutor.shutdownNow:

This implementation interrupts tasks via Thread.interrupt()

So you can use shutdownNow instead.

xingbin
  • 27,410
  • 9
  • 53
  • 103