Java CompletableFuture与ForkJoinPool的关系及说明

 更新时间:2025年05月29日 09:44:07   作者:学亮编程手记  
这篇文章主要介绍了Java CompletableFuture与ForkJoinPool的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

CompletableFuture 与 ForkJoinPool 的关系

CompletableFuture 默认使用 ForkJoinPool.commonPool() 来执行异步任务,但这不是唯一的选择。

1. 默认行为

当您使用以下方法创建异步任务时,默认会使用 ForkJoinPool.commonPool()

CompletableFuture.supplyAsync(() -> {...});  // 使用ForkJoinPool.commonPool()
CompletableFuture.runAsync(() -> {...});     // 使用ForkJoinPool.commonPool()

2. 自定义线程池

您也可以显式指定其他 Executor(线程池):

ExecutorService customExecutor = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync(() -> {...}, customExecutor);  // 使用自定义线程池

3. ForkJoinPool 的特点

ForkJoinPool.commonPool() 是一个共享的工作窃取线程池,具有以下特性:

  • 默认线程数等于 CPU 核心数减一(Runtime.getRuntime().availableProcessors() - 1)
  • 使用工作窃取(work-stealing)算法,适合处理大量小任务
  • 是 JVM 全局共享的,适合轻量级并行任务

4. 为什么选择 ForkJoinPool

Java 设计者选择 ForkJoinPool 作为默认实现是因为:

  1. 工作窃取算法:可以更好地利用多核处理器
  2. 适合异步任务CompletableFuture 通常用于组合多个小任务
  3. 避免线程创建开销:使用共享池减少资源消耗

5. 实际应用建议

  • CPU密集型任务:使用默认的 ForkJoinPool 通常效果不错
  • IO密集型任务:建议使用自定义的固定大小线程池(如 Executors.newFixedThreadPool
  • 长时间运行任务:避免使用公共池,以免影响其他使用公共池的功能

6. 示例代码

import java.util.concurrent.*;

public class CompletableFuturePoolExample {
    public static void main(String[] args) {
        // 默认使用ForkJoinPool.commonPool()
        CompletableFuture<Void> defaultPoolFuture = CompletableFuture.runAsync(() -> {
            System.out.println("Default pool - Thread: " + Thread.currentThread().getName());
        });
        
        // 使用自定义线程池
        ExecutorService customPool = Executors.newFixedThreadPool(2);
        CompletableFuture<Void> customPoolFuture = CompletableFuture.runAsync(() -> {
            System.out.println("Custom pool - Thread: " + Thread.currentThread().getName());
        }, customPool);
        
        // 等待任务完成
        CompletableFuture.allOf(defaultPoolFuture, customPoolFuture).join();
        customPool.shutdown();
    }
}

7. 注意事项

公共池的大小可以通过系统属性调整:

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "8");

在 Java 9+ 中,公共池的默认行为有所改变,使用更保守的线程数策略

总结

CompletableFuture 默认确实基于 ForkJoinPool,但可以根据需要灵活选择其他线程池实现。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 多线程_解决Runnable接口无start()方法的情况

    多线程_解决Runnable接口无start()方法的情况

    这篇文章主要介绍了多线程_解决Runnable接口无start()方法的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • java代码实现双向链表

    java代码实现双向链表

    这篇文章主要为大家详细介绍了java代码实现双向链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java数据结构优先队列实练

    Java数据结构优先队列实练

    通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西。但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出,这篇文章主要介绍了java优先队列的真题,感兴趣的朋友一起看看吧
    2022-07-07
  • MyBatis中特殊符号的转义

    MyBatis中特殊符号的转义

    编写SQL中会用到<,>,,>= 等,但是在mybatis中不可以这么写,与xml文件的元素冲突,所以需要转义,本文主要介绍了MyBatis中特殊符号的转义,主要介绍了两种转义方式,感兴趣的可以了解一下
    2024-01-01
  • SpringBoot创建动态定时任务的几种方式小结

    SpringBoot创建动态定时任务的几种方式小结

    SpringBoot提供了多种实现定时任务的方式,包括使用@Scheduled注解、SchedulingConfigurer接口、TaskScheduler接口和Quartz框架,@Scheduled适合简单的定时任务,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-10-10
  • SpringBoot2整合Drools规则引擎及案例详解

    SpringBoot2整合Drools规则引擎及案例详解

    这篇文章主要介绍了SpringBoot2整合Drools规则引擎及案例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Spring IoC 容器的使用详解(最新整理)

    Spring IoC 容器的使用详解(最新整理)

    文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean,实现依赖注入与动态获取,本文给大家介绍Spring IoC 容器的使用详解,感兴趣的朋友一起看看吧
    2025-07-07
  • Java实现ftp上传下载、删除文件及在ftp服务器上传文件夹的方法

    Java实现ftp上传下载、删除文件及在ftp服务器上传文件夹的方法

    这篇文章主要介绍了Java实现ftp上传下载、删除文件及在ftp服务器上传文件夹的方法,需要的朋友可以参考下
    2015-11-11
  • 很详细的Log4j配置步骤

    很详细的Log4j配置步骤

    Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的,它可接key=value格式的设置或xml格式的设置信息。通过配置,可以创建出Log4J的运行环境。
    2008-11-11
  • mybatis-plus 如何配置逻辑删除

    mybatis-plus 如何配置逻辑删除

    这篇文章主要介绍了mybatis-plus 如何配置逻辑删除,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论