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

时间:2016-10-23 19:43:49

标签: java multithreading concurrency java.util.concurrent futuretask

假设我有以下代码段:

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

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

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

3秒后失败

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

  

未来的实际工作是否继续执行?

是。除非您取消任务,否则任务执行将会进行。

  

或它被取消了吗?

没有。除非您取消它,否则不会取消。

  

我可以,稍后再过2秒,检索实际结果,还是不见了?

是。即使超时后您也可以获得结果。

查看示例代码段:

以下代码获取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)