有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java FutureTask中的多线程如果任务超时,任务是否会被取消?

假设我有以下代码段:

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

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

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

我的问题是:未来内部的实际工作是否继续得到执行?还是会被取消?我能在2秒钟后检索实际结果吗,还是它消失了


共 (2) 个答案

  1. # 1 楼答案

    Does the actual work inside future continue to executed?

    对。除非取消任务,否则任务将正在执行

    Or it does it get cancelled?

    不,除非你取消,否则不会取消

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

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

    查看示例代码段:

    下面的代码获取3秒超时后的future状态。我创建了人工延迟来演示这个例子。在实时情况下,如果没有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) 
    
  2. # 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