使用ExecutorService时不调用Thread.interrupt

时间:2014-04-16 07:21:29

标签: java multithreading threadpool interrupt

当我取消当前正在执行的任务时,我需要调用MyThread.interrupt()。为什么不是公共类主要{{/ p>

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    List<MyThread> threads = new ArrayList<Main.MyThread>();

    List<Future> futureList = new ArrayList<Future>();
    for (int i = 0; i < 30; i++) {
        MyThread myThread = new MyThread(i);
        futureList.add(executor.submit(myThread));
        threads.add(myThread);
    }
    for (Future future : futureList) {
        if (future != null) {
            future.cancel(true);
        }
    }

    // Calling interrupt directly. It works
    for (MyThread myThread : threads) {
        myThread.interrupt();
    }
    shutdownAndAwaitTermination(executor);

}

static void shutdownAndAwaitTermination(ExecutorService pool) {
    pool.shutdown(); // Disable new tasks from being submitted
    try {
        // Wait a while for existing tasks to terminate
        if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
            pool.shutdownNow(); // Cancel currently executing tasks
            // Wait a while for tasks to respond to being cancelled
            if (!pool.awaitTermination(10, TimeUnit.SECONDS)) System.err.println("Pool did not terminate");
            else System.out.println("Maybe OK");
        } else {
            System.out.println("OK");
        }
    } catch (InterruptedException ie) {
        // (Re-)Cancel if current thread also interrupted
        pool.shutdownNow();
        // Preserve interrupt status
        Thread.currentThread().interrupt();
    }
}

private static class MyThread extends Thread {

    HttpURLConnection connection;

    final int i;

    public MyThread(int i) {
        this.i = i;
    }

    @Override
    public void interrupt() {
        super.interrupt();
        if (connection != null) {
            connection.disconnect();
        }
    }

    @Override
    public void run() {
        // Initialize HttpURLConnection and upload / download data
    }

}

}

2 个答案:

答案 0 :(得分:7)

调用它,在此处更改并查看输出

...
            } catch (InterruptedException e) {
                System.out.println(i + " interrupted");
                Thread.currentThread().interrupt();
            }
...

问题是ThreadPoolExecutor使用自己的Thread来运行你的任务,它会中断这个线程而不是你的。扩展Thread是没有意义的,而是实现Runnable。如果您仍然使用Thread,那么您可以直接从MyThread.run()

调用MyThread.interrupt()

答案 1 :(得分:3)

executor.submit(new MyThread(i))有效,因为MyThread扩展了Thread,实现了Runnable

因此,run方法实际上是由您在线程池中启动的10个线程之一执行的。取消Future时,interrupt的{​​{1}}方法不会执行,因为它不是正在执行的线程,但被视为 a MyThread。然而,您的池启动的线程的Runnable被调用。