阿里开发手册为什么强制要求使用自定义线程池?

阿里开发手册为什么强制要求使用自定义线程池?

image-20240501111603586

上面这条开发规范来自阿里巴巴的开发手册,且是一条强制规范,所以为啥阿里不允许使用Executors去创建线程池呢?

我们先来介绍一下Executors

Executors

在Java中,我们可以通过Executors类来方便地创建和管理线程池,Executors类提供了一系列工厂方法来创建不同类型的线程池。

以下是四种常见的使用Executors创建的线程:

  1. newFixedThreadPool(int nThreads):创建一个固定大小的线程池,其中包含固定数量的线程。当线程池中的所有线程都在工作时,新任务会被放入队列中等待。

  2. newCachedThreadPool():创建一个可根据需要创建新线程的线程池。如果有空闲线程,则将重用空闲线程;否则创建新线程。适用于执行很多短期异步任务的程序。

  3. newSingleThreadExecutor():创建一个只有一个线程的线程池,保证任务按照指定顺序执行。

  4. newScheduledThreadPool(int corePoolSize):创建一个可以执行定时任务的线程池,可以延迟执行任务或定期执行任务。

这四种线程池可以应付开发中绝大部分场景,但是这四种线程池都存在一定问题,这也是为什么不建议用Executors来创建线程池的原因。

存在的问题

我把这4种线程池按照线程类型分成了两类:

newFixedThreadPool 和 newSingleThreadPool

uTools_1714534548849

uTools_1714534474475

可以从源码发现这两种线程池在创建时对应的阻塞队列都采用了LinkedBlockingQueue,这个LinkedBlockingQueue是一种基于链表的阻塞队列,正是由于它基于链表,长度无限制,所以就算有再多的任务进来也不会塞满这个阻塞队列,最终就会导致任务过多产生OOM异常。

newCachedThreadPool 和 newScheduledThreadPool

uTools_1714534878459

uTools_1714534878459

这两种线程池都没有使用LinkedBlockingQueue作为阻塞队列了,也就不存在我之前讲的那种问题,但是它们的最大线程数为Integer.MAX_VALUE,这就说明就算任务数再多,它们也能通过创建新的线程去处理,而当java进程中线程达到一定多的数量,这个进程就容易发生崩溃。

以上就是对阿里不推荐使用Executors创建线程池这条规范具体原因的说明,那我们应该如何正确地创建线程池,又该如何正确地在自己项目中使用线程池呢?

自定义线程池:ThreadPoolExecutor

在项目中,我们应该使用ThreadPoolExecutor来创建线程池,使用ThreadPoolExecutor创建的线程池具有更高的灵活性,足以满足我们日常的开发。

image-20240501120641535

分别介绍一下使用ThreadPoolExecutor来创建线程池时具体的参数:

  1. corePoolSize 核心线程数,开发中具体设定的值与电脑CPU和代码逻辑有关。

  2. maximumPoolSize 最大线程数,即核心线程数+临时线程数。

  3. keepAliveTime 线程存活时间,用来指定临时线程的生存时间,生存时间内没有新任务,该线程会被释放,核心线程则不会释放。

  4. unit 时间单位,临时线程生存时间的单位。

  5. workQueue 阻塞队列,当没有空闲的核心线程时,新来的任务会加入此队列,队列满时会创建临时线程执行任务。

  6. threadFactory 线程工厂,可以定制线程对象的创建,例如设置线程名字,是否是守护线程等。

  7. handler 拒绝策略,当所有的线程都在繁忙,workQueue也放满时,就会触发拒绝策略。

如何在项目中正确使用自定义线程池,请参考:在真实项目开发场景中正确使用线程池

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值