Future 超时后是不是会杀死线程?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Future 超时后是不是会杀死线程?相关的知识,希望对你有一定的参考价值。

参考技术A 不会删除,甚至不会尝试终端Task。

该方法的解释如下:

解释:

如果Task已经开始,那么mayInterruptIfRunning 参数会在尝试停止任务时,决定该执行该任务的线程是否应该被中断。

参考:
Stack Overflow:Does a Future timeout kill the Thread execution
Java doc:Future

未来超时是不是会终止线程执行

【中文标题】未来超时是不是会终止线程执行【英文标题】:Does a Future timeout kill the Thread execution未来超时是否会终止线程执行 【发布时间】:2013-04-20 08:04:59 【问题描述】:

当使用ExecutorServiceFuture 对象时(提交Runnable 任务时),如果我为future 的get 函数指定超时值,当TimeoutException 被抛出时,底层线程是否会被杀死?

【问题讨论】:

【参考方案1】:

它没有。为什么会呢?除非你告诉它。

例如,在 Callable 的情况下,这里有一个非常有效的问题。如果你等了 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
    

【讨论】:

只是评论:future.cancel(true); 确实停止正在运行的底层任务,它只是将正在运行的线程的中断标志设置为 true。您的代码负责检查此标志并在其为真时抛出 InterruptedException。 @ThiagoKronig,你确定吗?来自documentation,如果你传递true,线程应该被中断并且尝试应该失败。 @Dirk,来自我们的文档:如果任务已经开始,那么 mayInterruptIfRunning 参数决定执行这个任务的线程是否应该被中断 尝试停止任务Interruption 在这里意味着它将将该线程的 volatile 标志设置为 true。运行的代码必须测试这种情况才能自行停止。代码必须自行停止。 @Thiago 您能否分享有关如何在可调用对象中编码的示例代码/链接可以检查标志?代码究竟会检查什么?【参考方案2】:

不,它没有。 Morover甚至没有尝试打断任务。首先,带有超时的 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

【讨论】:

嗯...... 特别 Future 实现没有。因为它是一个界面,所以不能对所有Futures 做出笼统的陈述。 Future.get(long timeout, TimeUnit unit) 没有说它会尝试停止任务。另外,有很多方法可以停止正在运行的线程吗? 很好,我撤回投诉!【参考方案3】:

您似乎需要明确地终止、取消或关闭任务

Handling exceptions from Java ExecutorService tasks

How do I get FutureTask to return after TimeoutException?

【讨论】:

【参考方案4】:

只需运行这两行,程序永远不会终止! :

    Future<?> f = Executors.newSingleThreadExecutor().submit(() -> System.out.println("done"));
    f.get(1, TimeUnit.SECONDS);

【讨论】:

这与问题无关。 SingleThreadExecutor 中的默认线程工厂返回一个非守护线程,这就是它永远不会终止的原因。 Daemon Threads

以上是关于Future 超时后是不是会杀死线程?的主要内容,如果未能解决你的问题,请参考以下文章

Java 中 Future 的 get 方法超时会怎样?

java future.cancel方法是否直接杀死线程

Java 中 Future 的 get 方法超时会怎样?

Java 中 Future 的 get 方法超时会怎样?

Java程序执行超时——Future接口介绍

使用Future停止超时任务