在“Java 8 in action”(由 Urma、Fusco 和 Mycroft 撰写)一书中,他们强调并行流在内部使用公共(public) fork 连接池,并且可以全局配置,例如使用System.setProperty(...),不可能为单个并行流指定值。
从那以后,我看到了workaround,它涉及在定制的ForkJoinPool中运行并行流。
在本书的后面,他们有一整章专门介绍 CompletableFuture,在此期间他们有一个案例研究,比较了使用 parallelStream 与 CompletableFuture 的各自性能。事实证明它们的性能非常相似——它们强调了这样做的原因,因为它们都默认使用相同的公共(public)池(因此具有相同数量的线程)。
他们继续展示了一个解决方案,并认为 CompletableFuture 在这种情况下更好,因为它可以配置为使用自定义 Executor,具有用户选择的线程池大小。当他们更新解决方案以利用它时,性能会显着提高。
这让我想到 - 如果使用上面强调的解决方法对并行流版本做同样的事情,性能优势是否相似,因此这两种方法在性能方面会再次变得相似吗?在这种情况下,当开发人员显然需要做更多工作时,为什么要选择 CompletableFuture 而不是并行流。
最佳答案
恕我直言,这取决于您要支持的接口(interface)。如果您希望支持异步 API,例如
CompletableFuture<String> downloadHttp(URL url);
在这种情况下,只有可完成的 future 才有意义,因为您可能想要在等待数据下降的同时做一些不相关的事情。
另一方面,
parallelStream()
最适合 CPU 密集型任务,您希望每个任务都执行部分工作。即每个线程都用不同的数据做同样的事情。正如您所说,它也更易于使用。