【Java 并发编程】线程池机制 ( 线程池状态分析 | 线程池状态转换 | RUNNING | SHUTDOWN | STOP | TIDYING | TERMINATED )

简介: 【Java 并发编程】线程池机制 ( 线程池状态分析 | 线程池状态转换 | RUNNING | SHUTDOWN | STOP | TIDYING | TERMINATED )

文章目录

一、线程池状态分析





一、线程池状态分析


线程池的状态在 ThreadPoolExecutor 源码中定义 : private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)) 成员变量的 前 3 33 位是线程池的状态位 , 剩下的 29 2929 位是线程数 ;


public class ThreadPoolExecutor extends AbstractExecutorService {
  /**
  * 主池控制状态ctl是一个原子整数
  * 两个概念领域
  * workerCount,指示有效线程数
  * 运行状态,指示是否运行、关闭等
  * 
  * 为了将它们打包成一个整数,我们将workerCount限制为
  * (2^29)-1(约5亿)个线程,而不是(2^31)-1(2
  * 10亿)否则可代表。如果这曾经是一个问题
  * 将来,变量可以更改为原子长度,
  * 下面的移位/遮罩常数已调整。但在需要之前
  * 因此,此代码使用int更快更简单。
  * 
  * workerCount是已注册的工人数
  * 允许启动,不允许停止。该值可能是
  * 与活动线程的实际数量暂时不同,
  * 例如,ThreadFactory在以下情况下无法创建线程:
  * 当退出线程仍在执行时
  * 终止前的簿记。用户可见池大小为
  * 报告为工作集的当前大小。
  * 
  * 运行状态提供主要的生命周期控制,具有以下值:
  * 
  * 正在运行:接受新任务和处理排队的任务
  * 关机:不接受新任务,但处理排队的任务
  * 停止:不接受新任务,不处理排队的任务,
  * 并中断正在进行的任务
  * 整理:所有任务都已终止,workerCount为零,
  * 正在转换为状态整理的线程
  * 将运行终止的()钩子方法
  * 终止:终止()已完成
  * 
  * 这些值之间的数字顺序很重要,以允许
  * 有序比较。运行状态随时间单调增加
  * 时间,但不需要击中每个状态。这些转变是:
  * 
  * 运行->关机
  * 在调用shutdown()时,可能隐式地在finalize()中
  * (运行或关闭)->停止
  * 在调用shutdownNow()时
  * 关机->整理
  * 当队列和池都为空时
  * 停止->整理
  * 当池为空时
  * 清理->终止
  * 当终止的()钩子方法完成时
  * 
  * 等待终止()的线程将在
  * 国家终止。
  * 
  * 检测从关闭到清理的过渡较少
  * 比您希望的简单,因为队列可能会
  * 非空后为空,关机状态下为空,但
  * 只有在看到它是空的之后,我们才能终止
  * workerCount为0(有时需要重新检查——请参阅
  * 下)。
  */
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;
    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }
}


简单的机翻了下 , 如果查看详细的英文注释 , 查看 libcore/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java 源码 ;



RUNNING 状态 : 该状态下 可以接受新的 Runnable 任务 , 以及 处理阻塞队列中被添加的 Runnable 任务 ;


SHUTDOWN 状态 : 不接受新的 Runnable 任务 , 可以处理已经添加在阻塞队列中的 Runnable 任务 ;


STOP 状态 : 不接受新的 Runnable 任务 , 也不处理已经添加在阻塞队列中的 Runnable 任务 , 正在执行的任务也要中断 ;


TIDYING 状态 : 停止所有任务 , private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)) 变量设置为 0 00 ;


TERMINATED 状态 : 线程池彻底停止 ;


image.png


在 RUNNING 状态 , 调用 shutdown() 方法 , 跳转到 SHUTDOWN 状态 , 如果此时阻塞队列为空 , 线程池的工作线程为 0 00 , 就自动进入到 TIDYING 状态 ;

这里的工作线程指的是 核心线程 和 非核心线程 ;

线程池处于 RUNNING 状态下 , 正常运行 , 既可以处理新任务 , 也可以处理阻塞队列中的任务 ; 一旦调用 shutdown() 方法后 , 不再接受新任务 , 将阻塞队列中的残留任务执行完毕 , 然后进入 TIDYING 状态 ;



在 RUNNING 状态 , 调用 shutdownNow() 方法 , 跳转到 STOP 状态 , 此时强行将线程池的工作线程 ( 核心线程 和 非核心线程 ) 和 阻塞队列清空 , 处理完毕后 , 跳转到 TIDUING 状态 ;

也就是说 , 不等待当前正在执行的任务和阻塞队列中的任务执行完毕 , 立刻跳转到 TIDYING 状态 ;



在 TIDYING 状态下 , 一般是自动跳转到 TERMINATED 状态 ;


目录
相关文章
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
115 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
129 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
122 0
|
2月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
192 16
|
3月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
3月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
4月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
343 83
|
4月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
183 0
|
4月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
322 83