ExecutorService关闭不会中断线程

时间:2018-09-28 07:48:51

标签: java multithreading executorservice interrupt-handling

我尝试从布鲁斯·埃克尔(Bruce Eckel)的书“ 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();
    }
}

但是我有{strong>不正确的ExecutorService行为。当我调用shutdown方法时,线程不会中断并且不会继续工作。

但是如果我更改此示例并使用

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

在延迟调用submit.cancel(true之后)-线程中断正常。

看来,当您调用shutdown时,执行程序必须中断所有线程,并且我必须去捕获块(捕获InterruptedException),但这不起作用。

1 个答案:

答案 0 :(得分:1)

<script type="text/javascript" src="[host url]/app-env.js"></script> 在内部使用Executors.newCachedThreadPool作为线程池。

ThreadPoolExecutor.shutdown

  

启动有序关闭,其中先前提交的任务位于   执行,但不会接受新任务。

ThreadPoolExecutor.shutdownNow

  

此实现通过Thread.interrupt()中断任务

因此您可以改用ThreadPoolExecutor