java 多线程阻塞主线程 parallelStream || 程序计数器 + 线程池 || CompletableFuture使用性能经验

1。CompletableFuture

                    CompletableFuture<Map<Menu, Map<IntentDetail, Double>>> xxx= CompletableFuture.supplyAsync(() -> {
                        Map<Menu, Map<IntentDetail, Double>> scores = new ConcurrentHashMap<>();
                        return scores;
                    },addTaskExecutor);
                    // 等待所有计算完成并合并结果
                    CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                            xx,
                            xx,
                            xx,
                            xx,
                            xx
                    );

个人使用时,比较适合多个线程组合作处理逻辑时,但是真实体验下,性能较传统的程序计数器 + 线程池 性能低很多。

2。程序计数器 + 线程池

   CountDownLatch countDownLatch = new CountDownLatch(xx.size());
                for (xxx xxx: xxx) {
                    threadPool.submit(() -> {
                        try {

                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        } finally {
                            countDownLatch.countDown();
                        }
                    });
                }
                countDownLatch.await();

传统的计数器加线程池处理的模式,个人最喜欢使用的一种,性能也是三种里面最高(实测比CompletableFuture高)相对可控的一种方式。

3。parallelStream

 menuData.parallelStream().forEach(item->{});

parallelStream().forEach(…) 会阻塞主线程,直到所有并行任务完成。这使得你可以安全地在后续代码中依赖于并行处理的结果。

AI总结:
如果任务简单且是 CPU 密集型,使用 parallelStream 是个不错的选择;如果是 I/O 密集型或需要复杂的异步控制,CompletableFuture 更合适;对于需要高度定制的任务,程序计数器 + 线程池可能是最佳选择。

CompletableFuture
优点:
支持异步编程,适合处理非阻塞的任务。
可以组合多个异步任务,提供灵活的控制流。
缺点:
需要更多的代码来处理复杂的任务链。
对于 CPU 密集型任务,可能不如 parallelStream 高效。

程序计数器 + 线程池
优点:
可以根据具体需求自定义线程池大小和任务调度策略,灵活性高。
对于复杂的计算任务,可以通过合理的线程管理提高性能。
缺点:
实现复杂,代码可读性较差。
需要手动管理线程生命周期,容易引入错误。

parallelStream
优点:
简单易用,代码可读性强。
利用 Fork/Join 框架自动管理线程,提高 CPU 利用率。
缺点:
对于小规模任务,可能会引入额外的开销,导致性能下降。
对于 I/O 密集型任务,可能不如其他方式高效。

问题1:
parallelStream 和 程序计数器+ 线程池 哪个更快
性能比较
开销:
parallelStream: 在启动和管理线程方面的开销较高,尤其在数据量小的情况下,可能会因为线程管理的开销而导致性能下降。
线程池: 由于线程池复用线程,通常在高并发和大量任务时表现更好,尤其是任务粒度较大时。
任务粒度:
小任务: 对于小任务,parallelStream 可能会因为任务切分和合并的 overhead 而表现不佳。
大任务: 对于较大的任务,线程池可能会更高效,因为它可以避免频繁的线程创建和销毁。
灵活性与可控性
parallelStream:
使用简单,适合快速开发,但在复杂逻辑和错误处理方面灵活性较低。
线程池:
提供更多的控制和灵活性,适合复杂的并发场景,能够更好地处理错误和任务调度。
总结
小数据量: 在处理小数据量的情况下,线程池 通常会更快,因为 parallelStream 的开销可能会影响性能。
大数据量: 对于大数据量的计算,parallelStream 可能会更方便,但在性能上依赖于具体的任务和数据特性。
灵活性: 如果需要更高的灵活性和控制,程序计数器 + 线程池 是更好的选择。

问题2:并行流 和 CompletableFuture 在数据量小的情况下谁的性能更高啊
小数据量: 在小数据量的情况下,使用 并行流 (parallelStream) 性能更高且代码更简洁。
复杂任务: 如果未来需要更复杂的异步处理,可能再考虑使用 CompletableFuture。

  1. 任务类型
    CPU 密集型任务:
    线程池:可以通过自定义线程池的大小来优化性能,确保 CPU 资源被充分利用。
    CompletableFuture:虽然在 CPU 密集型任务中也能利用多线程,但通常不如专门的线程池灵活。
    I/O 密集型任务:

CompletableFuture:更适合,因为它可以处理异步 I/O 操作,避免线程阻塞,提高吞吐量。
线程池:如果线程池配置不当,可能导致线程阻塞,影响性能。

问题3:CompletableFuture 和 计数器+线程池谁的性能高啊

提供了更好的异步编程模型,支持任务组合和回调。
适合需要复杂控制流的场景。
线程池:
允许更细粒度的控制,但实现复杂度较高。
适合需要高度定制的任务调度。
3. 性能
基准测试:
实际性能往往取决于具体的实现和任务特性。对于简单的并行计算任务,线程池可能表现更好;而对于需要异步处理的任务,CompletableFuture 会更高效。
结论
CPU 密集型任务: 自定义线程池通常性能更高。
I/O 密集型任务: CompletableFuture 更具优势。
建议在实际应用中进行基准测试,以根据具体任务类型和环境选择最优方案。

注:问题3我保持个人建议,如果是复杂的组合类型,或者对性能要求没那么高同时希望能够很方便的管理线程,那使用CompletableFuture 是比较好的,除此之外我还是坚持 计数器+线程池 ,但是要保证计数器能够准确同时能释放,否则就是天塌了。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT_Octopus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值