在 Java FutureTask 中,如果任务超时,任务会被取消吗?

In Java FutureTask if the task Times out, does the Task get Cancelled?

假设我有以下代码片段:

FutureTask<?> f = new FutureTask<>(() -> { Thread.sleep(5000); return 1 + 2; })

myExecutor.execute(f);
f.get(3, TimeUnit.SECONDS);

根据编码,最后一行将在 3 秒后失败 java.util.concurrent.TimeoutException

我的问题是:future里面的实际工作会继续执行吗?或者它会被取消吗?我可以稍后再过 2 秒后检索实际结果,还是已经消失了?

继续执行。

通过添加第二个 f.get(3, TimeUnit.SECONDS); 您可以检索结果:

Object o2 = f.get(3, TimeUnit.SECONDS);
System.out.println("o2 = " + o2); // prints o2 = 3

您可以尝试调用

取消计算
f.cancel(true);

然后,当用

检索对象时
Object o2 = f.get(3, TimeUnit.SECONDS);

它抛出一个 CancellationException

Does the actual work inside future continue to executed?

Yes.The 任务将继续执行,除非您取消它。

Or it does it get cancelled?

没有。它不会取消,除非你取消它。

Could I, later, after another 2 seconds, retrieve the actual result, or is it gone?

是的。即使在超时后,您也可以稍后获得结果。

查看示例代码片段:

以下代码在 3 秒超时后获取未来的状态。我创建了人为延迟来演示示例。在没有 sleep() 方法的情况下,实时输出会有所不同。

public class FutureTaskQuery {
    public static void main(String args[]){
        ExecutorService executor = Executors.newFixedThreadPool(1);
        Future future = executor.submit(new MyCallable());
        try{
            Integer result = (Integer)future.get(3000, TimeUnit.MILLISECONDS);
        }catch(TimeoutException e){
            System.out.println("Time out after 3 seconds");
            //future.cancel(true);
        }catch(InterruptedException ie){
            System.out.println("Error: Interrupted");
        }catch(ExecutionException ee){
            System.out.println("Error: Execution interrupted");
        }   
        try{
            Thread.sleep(4000);
            Integer result = (Integer)future.get(2000, TimeUnit.MILLISECONDS);
            System.out.println("Result:"+result);
        }catch(Exception err){
            err.printStackTrace();
        }
        executor.shutdown();
    }
}

class MyCallable implements Callable<Integer>{
    public Integer call(){
        try{
            Thread.sleep(5000);
        }
        catch(Exception err){
            err.printStackTrace();
        }
        return 2;
    }
}

输出:

Time out after 3 seconds
Result:2

如果你取消下面行的评论

future.cancel(true);

输出:

Time out after 3 seconds
java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at MyCallable.call(FutureTaskQuery.java:31)
        at MyCallable.call(FutureTaskQuery.java:28)