未来超时会终止线程执行吗?

69

在使用ExecutorServiceFuture对象(提交Runnable任务)时,如果我给future的get函数指定了超时值,当抛出TimeoutException时,底层线程会被终止吗?

4个回答

80

它不会自动取消任务。除非您告诉它这样做。

例如,如果您等待一个可调用对象的结果20秒钟,但未获得结果,则表示您不再关心该结果。此时,您应该完全取消任务。

可以采用以下方式:

Future<?> future = service.submit(new MyCallable());
    try {
        future.get(100, TimeUnit.MILLISECONDS);
    } catch (Exception e){
        e.printStackTrace();
        future.cancel(true); //this method will stop the running underlying task
    }

37
只是一条评论:future.cancel(true);并不能停止正在运行的底层任务,它只是将运行线程的中断标志设置为true。你的代码需要负责检查这个标志,如果为true则抛出InterruptedException。 - Thiago Kronig
1
@ThiagoKronig,你确定吗?根据文档,如果你传递true,线程应该被中断并且尝试应该失败。 - Dirk
17
根据我们的文档,如果任务已经开始,则 mayInterruptIfRunning 参数决定是否应中断执行此任务的线程以尝试停止该任务。这里的“中断”意味着它将设置该线程的一个易失性标志为 true。运行的代码必须测试此条件才能停止自身。代码必须自我停止。 - Thiago Kronig
@Thiago,你能否分享一下在可调用函数内编写代码并检查标志的示例代码/链接?代码将会检查什么? - mtk

19

不,它没有。而且甚至没有尝试中断任务。首先,Future.get与超时并没有这样说。其次,请尝试我的测试以了解它的行为

    ExecutorService ex = Executors.newSingleThreadExecutor();
    Future<?> f = ex.submit(new Runnable() {
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("finished");
        }
    });
    f.get(1, TimeUnit.SECONDS);

1秒钟内打印

Exception in thread "main" java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:228)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at Test1.main(Test1.java:23)

再过1秒钟,任务将成功完成。

finished

1
嗯...那个特定的Future实现不支持。由于它是一个接口,我们不能对所有的Future做出笼统的陈述。 - Duncan Jones
7
Future.get(long timeout, TimeUnit unit) 方法并未表示它会尝试停止任务。此外,有许多方法可以停止正在运行的线程吗? - Evgeniy Dorofeev
2
好的回应,我撤回我的投诉! - Duncan Jones

5

-1
只需运行这两行代码,程序就永远不会终止!:
    Future<?> f = Executors.newSingleThreadExecutor().submit(() -> System.out.println("done"));
    f.get(1, TimeUnit.SECONDS);

这与问题无关。SingleThreadExecutor中的默认线程工厂返回一个非守护线程,这就是为什么它永远不会终止的原因。守护线程 - Miss Chanandler Bong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接