【问题标题】:Do I need to do a future.get() on a Future that doesn't return a value that I care about?我是否需要在未返回我关心的值的 Future 上执行 future.get() ?
【发布时间】:2023-03-31 04:40:03
【问题描述】:
我的 Java 应用程序使用 java.util.concurrent.Executors.newCachedThreadPool() 来启动许多不同的线程来执行不同类型的工作。
一些线程返回一个值。对于这些,我使用Future.get() 从线程中检索值。
其他线程不返回我关心的值。它们被声明返回Object,返回值始终为null。对于这些线程,我目前正在调用Future.get(),即使没有任何价值。这是必要的,还是毫无意义的?我的想法是,也许Future.get() 通知线程池我已完成此线程。
【问题讨论】:
标签:
java
concurrency
threadpool
executorservice
【解决方案1】:
简短的回答是否定的。但是,如果您想检查一切是否成功完成,Future.get() 将让您知道是否存在 ExecutionException(通过抛出它)。所以我通常称之为它,即使没有我关心的“结果”。 YMMV 取决于您如何进行错误处理。
正如汤姆安德森所提到的,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】:
在返回 null 的可调用任务上调用 Future.get() 没有错。请记住 Future.get() 块调用线程执行。通过这样做,您确实使工作线程与调用线程同步运行。顾名思义,Future.get() 是从未来获取一些东西,因此调用线程需要等待。
【解决方案3】:
据我所知,文档对此事保持沉默。但这意味着没有什么说你确实需要这样做。如果您确实需要,那会很奇怪 - 很容易因为忘记而意外搞砸线程池。
顺便说一句,这些无返回 Callables 的流行选择是 Callable<Void>。 Void 是an uninstantiable placeholder class,因此对于只会为空的变量来说这是一个不错的选择。