首页 > 其他分享 >记录一次代码中的ForkJoinPool.getCommonPoolParallelism()

记录一次代码中的ForkJoinPool.getCommonPoolParallelism()

时间:2024-06-21 10:44:42浏览次数:13  
标签:ForkJoinPool final 任务 线程 executor getCommonPoolParallelism 代码 ThreadPoolExecutor

@Configuration
@Slf4j
public class ThreadPoolConfig {

  private static final int CORE_POOL_SIZE = 6;
  private static final int MAX_POOL_SIZE = 12;
  private static final int KEEP_ALIVE_TIME = 60;
  private static final int QUEUE_CAPACITY = 200;
  private static final String THREAD_NAME_PREFIX = "completeFutureTaskExecutor-";
  private static final int AWAIT_TERMINATION_SECONDS = 120;

  @Bean("completeFutureTaskExecutor")
  public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(CORE_POOL_SIZE);
    executor.setMaxPoolSize(MAX_POOL_SIZE);
    executor.setQueueCapacity(QUEUE_CAPACITY);
    executor.setKeepAliveSeconds(KEEP_ALIVE_TIME);
    executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
    executor.setAwaitTerminationSeconds(AWAIT_TERMINATION_SECONDS);
    executor.setDaemon(Boolean.TRUE);

    // 线程池对拒绝任务的处理策略
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }

  @Bean("pmCompletableFutureExecutor")
  public Executor pmCompletableFutureExecutor() {

    final int parallelism = ForkJoinPool.getCommonPoolParallelism() * 3;

    log.info("加载自定义ForkJoinPool线程池, 线程池并行线程数量:{}, 线程数量为ForkJoinPool.getCommonPoolParallelism()*3", parallelism);

    ForkJoinPool buyForkJoinPool = new ForkJoinPool(parallelism);

    CompletableFutureUtils.load(buyForkJoinPool);

    return buyForkJoinPool;
  }

}

使用ForkJoinPool可以在有限的线程数下来完成非常多的具有父子关系的任务,比如使用4个线程来完成超过2000万个任务。但是使用ThreadPoolExecutor是不可能的,因为ThreadPoolExecutor中的线程无法选择优先执行子任务,要完成2000万个具有父子关系的任务时,就需要2000万个线程,这样会导致ThreadPoolExecutor的任务队列撑满或创建的最大线程数把内存撑爆直接gg。 

ForkJoinPool最适合计算密集型任务,而且最好是非阻塞任务,之前的一篇文章:Java踩坑记系列之线程池 也说了线程池的不同使用场景和注意事项。

所以ForkJoinPool是ThreadPoolExecutor线程池的一种补充,是对计算密集型场景的加强。

工作窃取的实现原理

每个线程都有自己的双端队列

当调用fork方法时,将任务放进队列头部,线程以LIFO顺序,使用push/pop方式处理队列中的任务

如果自己队列里的任务处理完后,会从其他线程维护的队列尾部使用poll的方式窃取任务,以达到充分利用CPU资源的目的

从尾部窃取可以减少同原线程的竞争

当队列中剩最后一个任务时,通过cas解决原线程和窃取线程的竞争

  1. 工作窃取便是ForkJoinPool线程池的优势所在,在一般的线程池比如ThreadPoolExecutor中,如果一个线程正在执行的任务由于某种原因无法继续运行,那么该线程会处于等待状态,包括singleThreadPoolfixedThreadPoolcachedThreadPool这几种线程池。

    而在ForkJoinPool中,那么线程会主动寻找其他尚未被执行的任务然后窃取过来执行,减少线程等待时间。

    JDK8中的并行流(parallelStream)功能是基于ForkJoinPool实现的,另外还有java.util.concurrent.CompletableFuture异步回调future,内部使用的线程池也是ForkJoinPool。

标签:ForkJoinPool,final,任务,线程,executor,getCommonPoolParallelism,代码,ThreadPoolExecutor
From: https://www.cnblogs.com/cp13215158435/p/18260068

相关文章

  • 【Python日志模块全面指南】:记录每一行代码的呼吸,掌握应用程序的脉搏
    文章目录......
  • 【YOLOv8改进】STA(Super Token Attention) 超级令牌注意力机制 (论文笔记+引入代码)
    摘要视觉Transformer在许多视觉任务上展示了卓越的性能。然而,它在浅层捕获局部特征时可能会面临高度冗余的问题。因此,使用了局部自注意力或早期阶段的卷积来减少这种冗余,但这牺牲了捕获长距离依赖的能力。一个挑战随之而来:在神经网络的早期阶段,我们是否能高效且有效地进行全局上......
  • 【YOLOv8改进】MLCA(Mixed local channel attention):混合局部通道注意力(论文笔记+引
    摘要本项目介绍了一种轻量级的MixedLocalChannelAttention(MLCA)模块,该模块同时考虑通道信息和空间信息,并结合局部信息和全局信息以提高网络的表达效果。基于该模块,我们提出了MobileNet-Attention-YOLO(MAY)算法,用于比较各种注意力模块的性能。在PascalVOC和SMID数......
  • 代码随想录刷题复习day01
    day01数组-二分查找classSolution{publicintsearch(int[]nums,inttarget){//左闭右闭intleft=0;intright=nums.length-1;intmid=0;while(right>=left){mid=left+(right-le......
  • 【Azure Event Hub】原生应用中使用RabbitMQ,是否可以不改动代码的情况下直接转换为使
    问题描述原生应用中使用RabbitMQ,是否可以不改动代码的情况下直接转换为使用AzureEventHub呢? 问题解答RabbitMQ使用的协议是AMQP0-9-1,而AzureEventHub或ServiceBus使用的是AMQP1.0,所以无法直接复用之前的代码。需要使用AzureEventHubSDK来生产/消费消息。Which......
  • Ant-Design-Vue动态表头并填充数据(含示例代码)
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • 【代码】--库函数学习 ftp通信 相关
    1. FTP介绍 (1)主动模式(PORT): 服务器主动去连接客户端的数据端口 (2)被动模式(PASV): 客户端主动去连接服务器的数据端口ftp客户端通信流程(编程流程)如下:1.客户端用账号、密码进行登录。2.提交主动模式还是被动模式。3.如果是被动模式,需要去连接服务器开放的数据......
  • Java跳动爱心代码
    1.计算爱心曲线上的点的公式计算爱心曲线上的点的公式通常基于参数方程。以下是两种常见的参数方程表示方法,用于绘制爱心曲线:1.1基于(x,y)坐标的参数方程x=a*(2*cos(θ)-sin(θ))^3y=a*(2*sin(θ)-cos(θ))^3其中,a是一个常数,用于控制爱心的大小;θ是参......
  • 进化计算常用的源代码平台
    InternationalJournalofComplexityinAppliedScienceandTechnology,收录进化计算,机器学习和大数据方面的论文,网址:https://www.inderscience.com/jhome.php?jcode=ijcast DEAP(DistributedEvolutionaryAlgorithmsinPython)简介:一个灵活且易于扩展的Python库,......
  • 好代码资源网整站打包代码(包含了最新数据),集成了深度二开的ripro主题,非常适合做资源网
    好代码资源网是基于wordpress开发的一个资源分享类网站,在开发者圈子里还算小有名气,这里分享婴整站打包代码(包含了最新数据)。网站本身集成了深度二开的ripro主题,非常适合做资源网站创业用。资源下载类网站目前还是红利期,搞个特价主机和域名,再用这个代码搭建起来就可以投入运营......