【问题标题】:Terminate underlying thread with future.cancel() to re-use the thread使用 future.cancel() 终止底层线程以重用线程
【发布时间】:2015-04-16 01:37:26
【问题描述】:
public class TestThreadTerminate {
    public static void main(String args[]) throws Exception {
        ExecutorService e = Executors.newCachedThreadPool();
        Future<Boolean> f = e.submit(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                System.out.println("Step 1!!");
                Thread.sleep(5000);
                System.out.println("Step 2!!");
                Thread.sleep(5000);
                System.out.println("Step 3!!");
                return true;
            }
        });
        try {
            Boolean flag = f.get(1, TimeUnit.SECONDS);
        } catch(TimeoutException ex) {
            f.cancel(true);
            System.out.println("Canceling");
        }
        System.out.println("FINAL!");
    }
}

有了这个,我的输出是

Step 1
Canceling
Final

但程序会在很久以后终止。为什么一旦线程中断就会发生这种情况?

如果我删除 f.cancel(true),我的线程会继续运行并打印以下内容:

Step 1
Canceling
Final
Step 2
Step 3

我可以做些什么来终止程序,即终止内部线程?实际上,我想将此线程用于线程池中的其他任务,这似乎不会发生在这里。

在返回之前将Thread.currentThread().isInterrupted() 放在所有地方看起来不是一个好主意。

【问题讨论】:

  • 您能否更好地格式化您的代码(并修复过程中的编译错误)?

标签: java multithreading concurrency threadpool futuretask


【解决方案1】:

为什么一旦线程中断就会发生?

这是因为您的线程池仍然处于活动状态 - 它可能会接受另一个要执行的可运行/可调用对象,因此在清理池中未使用的线程之前,它会等待查看是否发生这种情况。

缓存线程池的默认超时时间是 60 秒 - 这与您看到的相符吗?

如果您希望它更快地关闭,您应该致电e.shutdown()

【讨论】:

  • 啊啊啊,贴出来后才发现 :( 实际上,我的线程在其他任务之后可用,我不需要在 call() 方法中写任何东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
相关资源
最近更新 更多