Future的超时是否会终止Thread执行

Nic*_*men 54 java concurrency future executorservice

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

Eug*_*ene 54

它不是.为什么会这样?除非你告诉它.

例如,在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
    }
Run Code Online (Sandbox Code Playgroud)

  • 只是一个注释:`future.cancel(true);`确实**不会**停止正在运行的底层任务,它只是将正在运行的线程的中断标志设置为true.您的代码负责检查此标志并抛出InterruptedException(如果为true). (25认同)
  • @Dirk,来自我们的文档:_如果任务已经启动,那么mayInterruptIfRunning参数确定执行此任务_**的线程是否应该被中断以试图停止任务**._Interruption_ here表示将该线程的volatile标志设置为true.运行的代码必须测试此条件才能自行停止.代码必须自行停止. (12认同)

Evg*_*eev 16

不,它没有.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);
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

又过了1秒,任务成功完成

finished
Run Code Online (Sandbox Code Playgroud)

  • Future.get(长超时,TimeUnit单位)并没有说它会尝试停止任务.此外,还有很多方法可以阻止正在运行的线程吗? (6认同)
  • 反应很好,我撤回投诉! (2认同)