自定义线程池使用注意事项

Posted 爱叨叨的程序狗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义线程池使用注意事项相关的知识,希望对你有一定的参考价值。

03.线程池:业务代码最常用也最容易犯错的组件

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

线程池默认工作行为:

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

线程池的配置:

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

  • 对应执行比较慢、数量不大的IO任务,或许要考虑更多的线程数,而不需要太大的队列。
  • 而对于吞吐量交大的计算型任务,线程不宜过多,可以是CPU核心数或核心数*2,但可能需要较长的队列来做缓冲。

查询线程状态代码

    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);
    }

以上是关于自定义线程池使用注意事项的主要内容,如果未能解决你的问题,请参考以下文章

池化技术——自定义线程池

使用自定义线程池优化EchoServer

JAVA线程池配置及使用注意事项

QT 使用C++线程池运行Lambda自定义函数

QT 使用C++线程池运行Lambda自定义函数

如何自定义线程池工具类(ThreadPoolUtils)