欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java 线程池中的状态转换 - 使用位运算表示状态

程序员文章站 2022-03-06 18:37:29
java 线程池中的状态转换需要表示2种类型的状态, 1种是线程池是否在运行中, 1种是线程池中的有效线程数目.java源代码中, 并不使用2个变量来分别表示上面的状态, 而是使用1个整数来表示. 为此, 线程池限制了最大的线程数目为 (2^29)-1 而不是 (2^31)-1. 这样做的目的是使代码更快, 更简单.线程有以下的状态:RUNNING: 接受新的任务并处理队列中的任务SHUTDOWN: 不接受新的任务,但是继续处理队列中的任务STOP: 不接受新的任务,也不处理队列中的任务,并中...

java 线程池中的状态转换

需要表示2种类型的状态, 1种是线程池是否在运行中, 1种是线程池中的有效线程数目.

java源代码中, 并不使用2个变量来分别表示上面的状态, 而是使用1个整数来表示. 为此, 线程池限制了最大的线程数目为 (2^29)-1 而不是 (2^31)-1. 这样做的目的是使代码更快, 更简单.

线程有以下的状态:

  • RUNNING: 接受新的任务并处理队列中的任务
  • SHUTDOWN: 不接受新的任务,但是继续处理队列中的任务
  • STOP: 不接受新的任务,也不处理队列中的任务,并中断当前的任务
  • TIDYING: 所有的任务都停止, workerCount 为 0 , 线程转换为 TIDYING 状态, 将会执行 terminated() 钩子方法
  • TERMINATED: terminated() 调用完成

为了比较状态, 数字顺序是有用的. runState 是单调递增的:

  • RUNNING -> SHUTDOWN
    调用 shutdown() 的时候触发, 可能隐式地在 finally 块中调用
  • (RUNNING or SHUTDOWN) -> STOP
    调用 shutdownNow() 的时候触发
  • SHUTDOWN -> TIDYING
    当 任务队列 和 线程池 都为空的时候
  • STOP -> TIDYING
    当 线程池为空的时候
  • TIDYING -> TERMINATED
    terminated() 钩子函数执行完成的时候

awaitTermination() 中等待的线程会在状态达到 TERMINATED 的时候返回

SHUTDOWNTIDYING 的状态过渡并不直接, 因为 任务队列 可能 SHUTDOWN状态中由 非空之后变成空, 也可能由空变成非空. 但是我们能在 看到任务队列为空后, workerCount 也为空的情况下才进入 terminate.

源码状态定义:
java 线程池中的状态转换 - 使用位运算表示状态
这里面的 COUNT_BITS 就是 Integer.SIZE(32) - 3 = 29, 减去最高位的符号位, 用Integer 的最高两位来标识当前线程池的状态.

java 线程池中的状态转换 - 使用位运算表示状态
整个表示示意图如上, 其中CAPACITY就是 29 个1 , 当我们要拿当前线程池的状态的时候, 就用 c & ~CAPCITY 来清空后29位

private static int runStateOf(int c)     { return c & ~CAPACITY; }

需要拿线程数量的时候, 就用 c & CAPACITY; 来截取后29位

private static int workerCountOf(int c)     { return c & CAPACITY; }

ctlOf 函数表示合并 rs (running state)wc (workerCount), 所以初始化的 ctlclt(RUNNING,0), 表示运行状态 和 0 个 worker 数目. (这命名… 不算是好的实践吧)

private static int ctlOf(int rs, int wc) { rs | wc }

位运算的基础用法了.

本文地址:https://blog.csdn.net/sparrowxin/article/details/111875851

相关标签: java 线程池