avatar

线程池代码

代码的注释都写在了
这里


-

1. 线程的生命周期


ExecutorService主要功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 履行Ruannable类型的任务
* @param command
*/
void execute(Runnable command);

/**
* 可用来提交Callable或Runnable任务,并返回代表此任务的Future
* 对象
* @param task
* @param <T>
* @return
*/
<T> Future<T> submit(Callable<T> task);

/**
* 在完成已提交的任务后封闭办事,不再接管新任务
*/
void shutdown();

/**
* 停止所有正在履行的任务并封闭办事。
* @return
*/
List<Runnable> shutdownNow();

/**
* 测试是否所有任务都履行完毕了。
* @return
*/
boolean isTerminated();

/**
* 测试是否该ExecutorService已被关闭。
* @return
*/
boolean isShutdown();

2. 线程池的重点属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* ctl 是对线程池的运行状态和线程池中有效数量进行控制的一个字段,它包含两部分的信息:
* 线程池的运行状态(runState)
* 线程池内线程有效的线程数量(workerCount)
* 使用Integer类型来保存,高三位来保存runState,低29位来保存workerCount。
*
* COUNT_BITS 就是29
*
* COUNT_MASK 1左移29位-1,这个常量表示workerCount的上限值,大概是5亿左右
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;

// Packing and unpacking ctl

/**
* 这是是关于ctl的一些方法
* runStateOf 获取运行状态
* workerCountOf 获取活动线程数
* ctlOf 获取运行状态和活动线程数的值。
*
*/
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
private static int workerCountOf(int c) { return c & COUNT_MASK; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

// 线程池的5种状态
/**
* 高三位为111
* 1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行
* 处理。
* 2) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处
* 于RUNNING状态,并且线程池中的任务数为0!
*/
private static final int RUNNING = -1 << COUNT_BITS;
/**
*高三位为000
*1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
*2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。
*/
private static final int SHUTDOWN = 0 << COUNT_BITS;
/**
* 高三位为001
* 1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中
* 断正在处理的任务。
* 2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or
* SHUTDOWN ) -> STOP。
*/
private static final int STOP = 1 << COUNT_BITS;
/**
* 高三位为010
* 1) 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING
* 状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在
* ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;
* 可以通过重载terminated()函数来实现。
* 2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也
* 为空时,就会由 SHUTDOWN -> TIDYING。 当线程池在STOP状态下,线程池中执行的
* 任务为空时,就会由STOP -> TIDYING。
*/
private static final int TIDYING = 2 << COUNT_BITS;
/**
* 高三位为011
* 1) 状态说明:线程池彻底终止,就变成TERMINATED状态。
* 2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -
* > TERMINATED。
* 进入TERMINATED的条件如下:
* 线程池不是RUNNING状态;
* 线程池状态不是TIDYING状态或TERMINATED状态;
* 如果线程池状态是SHUTDOWN并且workerQueue为空;
* workerCount为0;
* 设置TIDYING状态成功。
*/
private static final int TERMINATED = 3 << COUNT_BITS;

3. 线程池的具体实现

ThreadPoolExecutor 默认的线程池
ScheduledThreadPoolExecutor 定时线程池

文章作者: 无知的小狼
文章链接: https://bytedance.press/2020/09/06/20200801/%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%BB%A3%E7%A0%81/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 无知的小狼

评论