当前位置: 首页 > news >正文

动态线程池中修改核心线程数比当前线程数要少,会不会影响正在执行的线程任务

目录

一、源码

二、interruptIdleWorkers() 源码

三、结论一句话

四、附:验证代码


不会。
ThreadPoolExecutor 里调 setCorePoolSize() 把核心线程数设得比当前活动线程数小时,不会中断或回收任何正在执行的任务。JDK 的实现逻辑是:

  1. 只会把“下一次”创建 Worker 时的核心阈值降低;
  2. 线程池会等到工作线程自然空闲(getTask() 返回 null)后,再根据 当前工作线程数 > 新核心线程数 的条件回收多余的 Worker;
  3. 正在 run() 的任务继续跑完,不会被强停。

因此,正在执行的任务不会受影响,只是当这批任务完成后,线程池会逐步把总线程数收缩到新的核心线程数。

一、源码

public void setCorePoolSize(int corePoolSize) {if (corePoolSize < 0 || maximumPoolSize < corePoolSize)throw new IllegalArgumentException();int delta = corePoolSize - this.corePoolSize;this.corePoolSize = corePoolSize;          // ① 先修改阈值// ② 当前工作线程数 > 新阈值 → 只中断“空闲”线程if (workerCountOf(ctl.get()) > corePoolSize)interruptIdleWorkers();                // 见下方源码// ③ 新阈值变大 → 按需补充线程else if (delta > 0) {int k = Math.min(delta, workQueue.size());while (k-- > 0 && addWorker(null, true)) {if (workQueue.isEmpty())break;}}
}

二、interruptIdleWorkers() 源码

private void interruptIdleWorkers() {interruptIdleWorkers(false);   // onlyOne=false
}private void interruptIdleWorkers(boolean onlyOne) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {for (Worker w : workers) {Thread t = w.thread;// 关键:线程必须“未持有任务”才会被打断if (!t.isInterrupted() && w.tryLock()) {try {t.interrupt();} finally {w.unlock();}}if (onlyOne)break;}} finally {mainLock.unlock();}
}
  • w.tryLock() 只有在 Worker 处于 getTask() 等待 时才会成功;
  • 正在 runTask() 的 Worker 已经拿到了锁,因此 不会 被打断。

三、结论一句话

降低核心线程数时,只会在任务执行结束后、线程空闲时再回收;正在跑的任务不会被中断或强制停止


四、附:验证代码

ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());// 先提交 5 个耗时任务
for (int i = 0; i < 5; i++) {pool.execute(() -> {System.out.println(Thread.currentThread().getName() + " start");try { Thread.sleep(3000); } catch (InterruptedException ignored) {}System.out.println(Thread.currentThread().getName() + " end");});
}Thread.sleep(1000);             // 确保线程已启动
pool.setCorePoolSize(2);        // 把核心数降到 2
System.out.println("核心线程数已设为 2,但正在运行的任务继续执行...");

输出示例:

pool-1-thread-1 start
pool-1-thread-2 start
...
核心线程数已设为 2,但正在运行的任务继续执行...
pool-1-thread-1 end
pool-1-thread-2 end
...

所有任务都完整跑完后,多余的线程才被回收,与源码逻辑完全吻合


文章转载自:

http://3Ng8gXE5.fqyqm.cn
http://KiHqOxOe.fqyqm.cn
http://8b6E8kRq.fqyqm.cn
http://jII3CJQF.fqyqm.cn
http://XsE8Unok.fqyqm.cn
http://fVOmAdAz.fqyqm.cn
http://YtkQ0td5.fqyqm.cn
http://hQy2ChD4.fqyqm.cn
http://8TRQqNhw.fqyqm.cn
http://uXZpJkg1.fqyqm.cn
http://4Tl7SzBT.fqyqm.cn
http://rNsKS8JX.fqyqm.cn
http://4UhhykR5.fqyqm.cn
http://mQ5rRNe6.fqyqm.cn
http://LJzEDgeG.fqyqm.cn
http://9fXYAIjr.fqyqm.cn
http://bI6b6WBG.fqyqm.cn
http://aJ2toPxC.fqyqm.cn
http://Iev3FWEm.fqyqm.cn
http://rNJPi5qL.fqyqm.cn
http://GQV3gADD.fqyqm.cn
http://ypu5ub7M.fqyqm.cn
http://TvFHvaCq.fqyqm.cn
http://OZAdzCGo.fqyqm.cn
http://vVE1firY.fqyqm.cn
http://Az6FPAEQ.fqyqm.cn
http://gUgUOrNq.fqyqm.cn
http://li6m6dkv.fqyqm.cn
http://zdJ6IMRT.fqyqm.cn
http://DLAxIlUC.fqyqm.cn
http://www.dtcms.com/a/373107.html

相关文章:

  • Axum文档 ~ 2.路由
  • 【C++】IO库
  • 常见的显示器接口技术
  • 如何在本地机器上使用LLM构建知识图谱(一)
  • 论文阅读:ACL 2023 MPCHAT: Towards Multimodal Persona-Grounded Conversation
  • Java全栈开发工程师的实战面试:从基础到微服务
  • 向量回归策略
  • 【数据库】时序数据库科学选型,以IoTDB构筑大数据时代的时序数据底座
  • MAUI劝退:安卓实体机测试
  • Day8 C++
  • 在线教程 | VibeVoice-1.5B独创双Tokenizer架构实现一次性生成90分钟4人对话语音,重新定义TTS技术边界
  • 《练手:ipv4地址计算和Telnet 远程设备管理配置实验文档》
  • [论文阅读] 人工智能 + 软件工程 | TDD痛点破解:LLM自动生成测试骨架靠谱吗?静态分析+专家评审给出答案
  • 【计算机网络 | 第10篇】信道复用技术
  • Pytest+requests进行接口自动化测试1.0(基础知识 + 测试用例 + request库)
  • 使用 OpenLayers + 高德瓦片源实现旅游足迹地图
  • 2025年体制内职业发展相关资格认证参考指南
  • window显示驱动开发—监视筛选器驱动程序(三)
  • 计算机网络:数据链路层--数据链路层基本功能
  • 第二课、熟悉Cocos Creator 编辑器界面
  • [Wit]CnOCR模型训练全流程简化记录(包括排除BUG)
  • JavaEE 进阶第四期:开启前端入门之旅(四)
  • TFS-2004《Input Selection for Nonlinear Regression Models》
  • esp下载器使用流程
  • 3dtiles 加载问题
  • 3D地球可视化教程 - 第1篇:基础地球渲染系统
  • 单片机开发
  • LLMs之REFRAG:《REFRAG: Rethinking RAG based Decoding》的翻译与解读
  • MATLAB的数值计算(二)线性方程求解
  • Java基础(十一):关键字final详解