Java ExecutorsService提交FutureTask get on Future返回null

时间:2019-04-20 12:27:35

标签: java future executorservice java.util.concurrent futuretask

我有这个片段。

    final ExecutorService executor = Executors.newFixedThreadPool(3);
    final Runnable runnable = ()->{System.out.println("Inside runnable run method");};
    final Callable<String>callable = ()->{System.out.println("Inside callable call method");return "callable";};
    final FutureTask<String> futureTask = new FutureTask<>(()->{System.out.println("CallableInFutureTask");},"JOHN");
    final FutureTask f1 = (FutureTask)executor.submit(callable);
    final FutureTask f2 = (FutureTask)executor.submit(futureTask);
    final FutureTask f3 = (FutureTask)executor.submit(runnable);
    System.out.println("f1 = " + f1+" "+f1.isDone()+" "+f1.get());
    System.out.println("FutureTask Reference Object: "+futureTask.isDone()+" "+futureTask.get());
    System.out.println("f2 = "+f2.isDone()+" "+f2.get());
    System.out.println("f3 = " + f3+" "+f3.isDone()+" "+f3.get());        
    executor.shutdown();

f1和f3 Future变量返回其get方法的正确值,但是FutureTask将其传递给执行器f2返回null为什么这是为什么?甚至futureTask引用也为get方法返回正确的值“ JOHN”,但这为什么呢?也许是因为我通过了FutureTask?我不明白。

我只是认为f2和futureTask引用将返回相同的值。很抱歉,这个问题很简单。

2 个答案:

答案 0 :(得分:2)

当您将FutureTask提交给ExecutorService时,它被视为Runnable,因此从Future方法获得的submit将具有值null,因为Runnable实例不返回任何结果。

由于FutureTask实现了Runnable接口,因此ExecutorService的该方法被称为submit(Runnable task),因此Runnable被包装在{{1}中}构造函数实际上已提交给FutureTask,因此在调用ExecutorService时会得到null。

但是,当您在f2.get()引用上调用get()时,一旦FutureTask完成了执行后,您将取回作为第二个参数提供的值< / em>(当您在Runnable之前提交任务时)。

您还可以通过不在ExecutorService中提交{em> futureTask来验证这一点,然后如果尝试调用ExecutorService变量上的get {{ 1}}调用将无限期地阻塞,因为futureTask尚未执行。

get

这是根据docs

  

创建一个FutureTask,它将在运行时执行给定的   可运行,并安排get将在给定的结果上返回   成功完成。

答案 1 :(得分:1)

这是正确的回报。 f1有回报,但f2和f3没有回报。 null代表 void