如何使用单线程执行器中断未来的工作?

时间:2017-09-15 15:45:33

标签: java multithreading future executor

如果我经常安排要使用Executor.newSingleThreadExecutor()取消的要运行的任务,future.cancel(true);如何表现?

执行程序生成的单个线程是否被中断(因此将来的代码需要清除中断),或者在下一个未来启动时是否会自动清除中断标志。

Executor是否需要在剩余任务队列使用的每个中断上产生一个额外的线程?

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

以下示例程序演示如果使用true调用cancel方法,则会在线程上调用中断。你甚至可以看到它正在重用同一个线程。 cancel返回一个布尔值,表示取消是否成功。这种方法的javadoc也很清楚。

class Task implements Callable<String> {

    @Override
    public String call() throws Exception {
        try {
            System.out.println("Thread name = " + Thread.currentThread().getName());
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
            return "Interruped";
        }
        return "X";
    }
}
public class Testy {


    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService =
                Executors.newSingleThreadExecutor();
        int count = 0;
        while (true) {
            System.out.println("Iteration " + count++);
            Future<String> submit = executorService.submit(new Task());
            Thread.sleep(500);
            submit.cancel(true);
        }

    }
}

输出如下所示

Iteration 0
Thread name = pool-1-thread-1
Iteration 1
Interrupted
Thread name = pool-1-thread-1
Iteration 2
Interrupted

答案 1 :(得分:1)

好问题,我没有在任何地方找到这些文件,所以我想说它是依赖于实现的。

例如,OpenJDK会在每个执行的任务之前重置中断标志:

// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted.  This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
     (Thread.interrupted() &&
      runStateAtLeast(ctl.get(), STOP))) &&
    !wt.isInterrupted())
    wt.interrupt();

来自OpenJDK jdk8u ThreadPoolExecutor#runWorker source的摘录。