Executors:为什么阿里不待见我?

CachedThreadPool是一个会根据需要创建新线程的线程池。

实现源码:

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

直接调用ThreadPoolExecutor的构造方法。

  • 核心线程数为0,最大线程数是非常大的一个数字Integer.MAX_VALUE

  • 使用没有容量的SynchronousQueue作为工作队列

  • keepAliveTime设置为60L,空闲线程空闲60秒之后就会被终止

CachedThreadPool的运行流程:

CachedThreadPool执行流程

  • 如果当前有空闲线程,使用空闲线程来执行任务

  • 如果没有空闲线程,创建一个新线程来执行任务

  • 新建的线程执行完任务后,会执行poll(keepAliveTime,TimeUnit.NANOSECONDS),在SynchronousQueue里等待60s

这里线程池的大小没有限制,可能会无限创建线程,导致OOM

4. newScheduledThreadPool


ScheduledThreadPool是一个具备调度功能的线程池。

实现源码:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

return new ScheduledThreadPoolExecutor(corePoolSize);

}

可以看到,这个线程池不太一样,它调用的是ScheduledThreadPoolExecutor的构造方法。

public ScheduledThreadPoolExecutor(int corePoolSize) {

super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

new DelayedWorkQueue());

}

  • 最大线程数是Integer.MAX_VALUE,无限大

  • 使用DelayedWorkQueue作为任务队列

ScheduledThreadPoolExecutor执行任务的流程:

ScheduledThreadPool执行流程

主要分为两大部分:

  1. 调用scheduleAtFixedRate()/scheduleWithFixedDelay()方法,会向DelayQueue添加一个ScheduledFutureTask

  2. 线程池的线程从DelayQueue中获取ScheduledFutureTask,然后执行任务。

它同样可以无限创建线程,所以也存在OOM的风险。

为了实现周期性执行任务,ScheduledThreadPoolExecutorThreadPoolExecutor进行了一些改造[4]:

  • ScheduledFutureTask来作为调度任务的实现

它主要包含了3个成员变量time(任务将要被执行的具体时间)sequenceNumber(任务的序号)period(任务执行的间隔周期)

  • 使用DelayQueue作为任务队列

DelayQueue封装了了一个PriorityQueue,会对对队列中的ScheduledFutureTask进行排序,排序的优先级time>sequenceNumber。

ScheduledThreadPoolExecutor执行流程

ScheduledThreadPoolExecutor的任务执行主要分为4步:

  1. 线程池里的线程1DelayQueue中获取已到期的ScheduledFutureTask(DelayQueue.take())

  2. 线程1执行这个ScheduledFutureTask

  3. 线程1修改ScheduledFutureTasktime变量为下次将要被执行的时间。

  4. 线程1把这个修改time之后的ScheduledFutureTask放回DelayQueue中(DelayQueue.add())


Excutors自述:这,这……工具类出的问题不叫bug。虽然我偷懒不干活,还可能会OOM,但我还是一个好工具类,呜呜……

作者:是啊,其实Excutors有什么错呢?它只是一个没得感情的工具类,有错的只是不恰当地用它的人。所以,知其然且知其所以然,搞懂原理,灵活应用。我们应该像一个士兵一样,不只是会扣动扳机,还会拆解保养枪械。

我是三分恶,一个号称能文能武的全栈开发。

点赞关注不迷路,咱们下期见!


参考:

[1]. 《Java并发编程的艺术》

[2]. 讲真 这次绝对让你轻松学习线程池

[3]. 小傅哥 《Java面经手册》

[4]. 《Java并发编程之美》

[5]. 阿里巴巴《Java开发手册》
更多精彩原创,技术交流👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值