为什么我不能取消我的遗嘱执行人提交的工作?

Why can't I cancel my executor submited job?

我试图取消使用此代码提交的主题,但没有成功

  ExecutorService executor = Executors.newSingleThreadExecutor();
  Future<Object> future = executor.submit(()-> {while(true) { System.out.println("Thread"); Thread.yield();} } );
  Thread.sleep(3000);
  future.cancel(true);
  executor.shutdown();

但线程保持不变 运行。 当使用 sleep 而不是 yield 时,线程确实会被取消。例如,这会取消线程:

  ExecutorService executor = Executors.newSingleThreadExecutor();
  Future<Object> future = executor.submit(()-> {while(true) { System.out.println("Thread"); Thread.sleep(1000);} } );
  Thread.sleep(3000);
  future.cancel(true);
  executor.shutdown();

这是怎么回事?我在文档中遗漏了什么吗?

您的第一个任务对中断没有响应。但是第二个任务是响应式的,因为Thread.sleep是一个响应中断的阻塞方法。解决该问题的一种方法是让您的任务响应中断。这是它的样子。

Future<?> future = executor.submit(() -> {
    while (!Thread.currentThread().isInterrupted())
        System.out.println("Thread");
});

此外 Thread.yield 只是一个调度程序提示,以产生其当前使用的处理器。此操作依赖于平台,不应在实践中使用。因此,我已将其从我的答案中删除。

如果您打算停止所有已提交的任务,您可以使用

executor.shutdownNow();

Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()


正如问题的评论部分中已经提到的,中断调用.sleep(1000).yield()行为之间的区别