线程池如何保证核心线程一直存活
2023-04-18 13:06:32 时间
转载请注明出处:
查看 ThreadPoolExecutor 类中的 getTask 方法,这个方法可以保持核心线程在没有任务的时候也可以一直处于存活状态
/**
* Performs blocking or timed wait for a task, depending on
* current configuration settings, or returns null if this worker
* must exit because of any of:
* 1. There are more than maximumPoolSize workers (due to
* a call to setMaximumPoolSize).
* 2. The pool is stopped.
* 3. The pool is shutdown and the queue is empty.
* 4. This worker timed out waiting for a task, and timed-out
* workers are subject to termination (that is,
* {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
* both before and after the timed wait, and if the queue is
* non-empty, this worker is not the last thread in the pool.
*
* @return task, or null if the worker must exit, in which case
* workerCount is decremented
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
核心在于 workQueue.poll 和 workQueue.take() 两个方法,且前面会判断 当前线程数,如果 当前线程数等于核心线程数时,就会调用 take 方法,让线程向队列获取任务的状态一直保持阻塞状态,通过这个方法就可以保证核心线程一直存活状态。
看下 take 与 poll 方法的区别:
take:会响应中断,会一直阻塞直到取得元素或当前线程中断。如果队列中没有数据,则线程wait释放CPU
poll:会响应中断,会阻塞,阻塞时间参照方法里参数 timeout,timeUnit,当阻塞时间到了还没取得元素会返回null
相关文章
- nuxt3项目初始化失败 getaddrinfo ENOENT raw.githubusercontent.com 报错
- 袋鼠云出品!数栈UI 5.0全新体验升级,设计背后的故事
- Hbuilder项目转vue-cli项目
- 使用VS code将本地的项目推送到gitee的方法(图例)
- 1.5.5 HDFS读写解析-hadoop-最全最完整的保姆级的java大数据学习资料
- 数据安全新战场,EasyMR为企业筑起“安全防线”
- 1.5 HDFS分布式文件系统-hadoop-最全最完整的保姆级的java大数据学习资料
- 【NoSql】缓存管理器CacheManager使用
- DTALK直播预约 | 12月8日开播:后疫情时代,制造企业如何实现数字化转型?
- Delete ␍eslint(prettierprettier)错误
- DBeaver企业版免费下载及破解(白嫖党福利)
- SQL Server(解决问题)已成功与服务器建立连接,但是在登录过程中发生错误。provider: Shared Memory Provider, error:0 - 管道的另一端上无任何进程。
- 前端面试题学习-个人总结笔记 Day 1
- 合并代码注意事项
- flex布局 -- 弹性盒模型
- 大数据技术的现状与面临的挑战
- 网页DOM编程方法(API总结与应用)
- 袋鼠云数栈UI5.0体验升级背后的故事:可用性原则与交互升级
- CSS 网格(Grid)布局
- 聊聊Cookie、Session、Token 背后的故事