前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何合理使用线程池?

如何合理使用线程池?

作者头像
关忆北.
发布2021-12-07 16:42:07
7400
发布2021-12-07 16:42:07
举报
文章被收录于专栏:关忆北.关忆北.关忆北.
线程池

创建线程池要使用手动方式,自动创建线程使用newFixedThreadPool和newCachedThreadPool可能因为资源耗尽导致OOM问题。

原因:Executors会根据数据量创建固定个数的线程,而Executors.newFixedThreadPool方法会创建一个LinkedBlockingQueue消息队列,查看消息队列的构造方法可以看的是该队列的长度是Integer.MAX_VALUE,可以认为是一个无边界的队列,当数据量较大时(如大量入库操作)且执行较慢时,会导致创建不可控数量的无限队列,导致OOM。

image-20210707102328586
image-20210707102328586
合理使用线程池
  1. 线程池需根据业务场景做到线程数量、最大线程数、队列长度、拒绝策略可控。
  2. 线程池需要根据业务场景有不同的名称,以方便排查错误,分析高耗时操作。

所以显然Executors是不符合使用需求且不安全的。

线程池默认工作行为:

  • 不会初始化corePoolSize个线程,有任务来了才创建工作线程
  • 当核心线程满了之后不会立即扩容线程池,而是把任务堆积到工作队列中
  • 当工作队列满了后扩容线程池,一直到线程个数到maximumPoolSize为止
  • 如果队列已满且达到最大线程后还有任务进来,按照拒绝策略处理
  • 当线程数大于核心线程数时,线程等待KeepAliveTime后还是没有任务需要处理的话,收缩线程到核心线程数
务必清楚线程池本身是不是复用的

线程池的配置:

根据任务的“轻重缓急”来指定线程池的核心参数,包括线程数、回收策略和任务队列

  • 对应执行比较慢、数量不大的IO任务,或许要考虑更多的线程数,而不需要太大的队列。
  • 而对于吞吐量交大的计算型任务,线程不宜过多,可以是CPU核心数或核心数*2,但可能需要较长的队列来做缓冲。
线程池默认工作行为
  • 不会初始化corePoolSize个线程,有任务来了才创建工作线程;
  • 当核心线程满了之后不会立即扩容线程池,而是把任务堆积到工作队列中;
  • 当工作队列满了后扩容线程池,一直到线程个数到maximumPoolSize为止;
  • 如果队列已满且到达最大线程后还有任务进来,则采取拒绝策略;
  • 当线程数大于核心线程数时,线程等待keepAliveTime后还是没有任务需要处理的话,收缩线程数到核心线程数;
  • 声明线程池后立即调用prestartAllCoreThreads方法,来启动所有的核心线程;
  • 传入true给allowCoreThreadTimeOut方法,来让线程池在空闲的时候同样回收核心线程。
查询线程状态代码
    private void printStats(ThreadPoolExecutor threadPool) {
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            log.info("=========================");
            log.info("Pool Size: {}", threadPool.getPoolSize());
            log.info("Active Threads: {}", threadPool.getActiveCount());
            log.info("Number of Tasks Completed: {}", threadPool.getCompletedTaskCount());
            log.info("Number of Tasks in Queue: {}", threadPool.getQueue().size());
            log.info("=========================");
        }, 0, 1, TimeUnit.SECONDS);
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-05-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线程池
  • 合理使用线程池
    • 务必清楚线程池本身是不是复用的
    • 线程池默认工作行为
    • 查询线程状态代码
    相关产品与服务
    消息队列 CMQ 版
    消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档