我是否需要对未返回我关心的值的Future执行future.get()?

时间:2011-11-23 23:47:13

标签: java concurrency threadpool executorservice

我的Java应用程序使用java.util.concurrent.Executors.newCachedThreadPool()来启动许多不同的线程来完成不同的工作。

某些线程返回一个值。对于这些,我使用Future.get()从线程中检索值。

其他线程不返回我关心的值。声明它们返回Object,返回的值始终为null。对于这些线程,我正在调用Future.get(),即使没有值得到。这是必要的,还是没有意义?我的想法是,也许Future.get()通知线程池我已经完成了这个线程。

3 个答案:

答案 0 :(得分:1)

对可返回null的可调用任务调用Future.get()没有错。请记住,Future.get()阻止调用线程执行。通过这样做,您确实使工作线程与调用线程同步运行。正如它的名字所述,Future.get()从未来获得了一些东西,因此调用线程需要等待。

答案 1 :(得分:1)

简短的回答是否定的。但是,如果你想检查一切是否成功完成,Future.get()会告诉你是否有ExecutionException(通过抛出它)。所以我通常称之为,即使没有我关心的“结果”。 YMMV取决于您如何进行错误处理。

正如Tom Anderson所提到的,Callable<Void>是一种提醒人们没有“结果”的选项。但坦率地说,我的Callables意味着Executor几乎总是回归自己,所以如果需要你可以真正仔细检查结果。例如(有点夸张)

public class LongCalculation implements Callable<LongCalculation> {

   public double getResult() { ... }
   public SomeEnum getStatus() { ... } // e.g. FAILED, SUCCESS, CANCELLED
   public List<String> getAnythingWeirdThatHappenned() { ... }
}

答案 2 :(得分:0)

据我所知,文件对此事没有提及。但这意味着没有什么可以说你需要这样做。如果你确实需要这将是非常奇怪的 - 通过忘记来意外搞砸一个线程池是非常容易的。

顺便说一下,这些无回报的Callables的热门选择是Callable<Void>。 Void是an uninstantiable placeholder class,因此对于只会为null的变量来说它是一个很好的选择。