Skip to content

Commit d328d16

Browse files
committed
👌 Updating code due to code review changes.
1 parent 72e867f commit d328d16

1 file changed

Lines changed: 14 additions & 13 deletions

File tree

docs/thread/ThreadPoolExecutor.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
![](https://ws1.sinaimg.cn/large/006tKfTcgy1ftpwh3a2szj31kw11xh84.jpg)
1+
![](https://i.loli.net/2019/05/08/5cd1d2a867bea.jpg)
22

33
## 前言
44

55
平时接触过多线程开发的童鞋应该都或多或少了解过线程池,之前发布的《阿里巴巴 Java 手册》里也有一条:
66

7-
![](https://ws2.sinaimg.cn/large/006tKfTcgy1ftpxf3x1epj30la03s0tl.jpg)
7+
![](https://i.loli.net/2019/05/08/5cd1d2a8dad64.jpg)
88

99
可见线程池的重要性。
1010

@@ -26,6 +26,7 @@
2626
- `Executors.newFixedThreadPool(nThreads)`:创建固定大小的线程池。
2727
- `Executors.newSingleThreadExecutor()`:创建单个线程的线程池。
2828

29+
<!--more-->
2930

3031
其实看这三种方式创建的源码就会发现:
3132

@@ -67,7 +68,7 @@ threadPool.execute(new Job());
6768

6869
在具体分析之前先了解下线程池中所定义的状态,这些状态都和线程的执行密切相关:
6970

70-
![](https://ws3.sinaimg.cn/large/006tKfTcgy1ftq1ks5qywj30jn03i3za.jpg)
71+
![](https://i.loli.net/2019/05/08/5cd1d2a9bc566.jpg)
7172

7273
- `RUNNING` 自然是运行状态,指可以接受任务执行队列里的任务
7374
- `SHUTDOWN` 指调用了 `shutdown()` 方法,不再接受新任务了,但是队列里的任务得执行完毕。
@@ -77,22 +78,22 @@ threadPool.execute(new Job());
7778

7879
用图表示为:
7980

80-
![](https://ws4.sinaimg.cn/large/006tKfTcgy1ftq2nxlwe5j30sp0ba0ts.jpg)
81+
![](https://i.loli.net/2019/05/08/5cd1d2aa81655.jpg)
8182

8283
然后看看 `execute()` 方法是如何处理的:
8384

84-
![](https://ws1.sinaimg.cn/large/006tKfTcgy1ftq283zi91j30ky08mwgb.jpg)
85+
![](https://i.loli.net/2019/05/08/5cd1d2ab921db.jpg)
8586

8687
1. 获取当前线程池的状态。
8788
2. 当前线程数量小于 coreSize 时创建一个新的线程运行。
8889
3. 如果当前线程处于运行状态,并且写入阻塞队列成功。
89-
4. 双重检查,再次获取线程池状态;如果线程池状态变了(非运行状态)就需要从阻塞队列移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。
90+
4. 双重检查,再次获取线程状态;如果线程状态变了(非运行状态)就需要从阻塞队列移除任务,并尝试判断线程是否全部执行完毕。同时执行拒绝策略。
9091
5. 如果当前线程池为空就新创建一个线程并执行。
9192
6. 如果在第三步的判断为非运行状态,尝试新建线程,如果失败则执行拒绝策略。
9293

9394
这里借助《聊聊并发》的一张图来描述这个流程:
9495

95-
![](https://ws4.sinaimg.cn/large/006tKfTcgy1ftq2vzuv5rj30dw085q3i.jpg)
96+
![](https://i.loli.net/2019/05/08/5cd1d2ac0936c.jpg)
9697

9798

9899
### 如何配置线程
@@ -206,16 +207,16 @@ public class TreadPoolConfig {
206207

207208
其实 ThreadPool 本身已经提供了不少 api 可以获取线程状态:
208209

209-
![](https://ws1.sinaimg.cn/large/006tKfTcgy1ftq3xsrbs6j30bg0bpgnb.jpg)
210+
![](https://i.loli.net/2019/05/08/5cd1d2accbbcf.jpg)
210211

211212
很多方法看名字就知道其含义,只需要将这些信息暴露到 SpringBoot 的监控端点中,我们就可以在可视化页面查看当前的线程池状态了。
212213

213214

214215
甚至我们可以继承线程池扩展其中的几个函数来自定义监控逻辑:
215216

216-
![](https://ws2.sinaimg.cn/large/006tKfTcgy1ftq40lkw9jj30mq07rmyt.jpg)
217+
![](https://i.loli.net/2019/05/08/5cd1d2add4d31.jpg)
217218

218-
![](https://ws4.sinaimg.cn/large/006tKfTcgy1ftq41asf8rj30kq07cabd.jpg)
219+
![](https://i.loli.net/2019/05/08/5cd1d2aeea439.jpg)
219220

220221
看这些名称和定义都知道,这是让子类来实现的。
221222

@@ -383,7 +384,7 @@ public class CommandUser extends HystrixCommand<String> {
383384

384385
运行结果:
385386

386-
![](https://ws2.sinaimg.cn/large/006tKfTcgy1ftq4e0ukubj30ps04gtak.jpg)
387+
![](https://i.loli.net/2019/05/08/5cd1d2b06ef2d.jpg)
387388

388389
可以看到两个任务分成了两个线程池运行,他们之间互不干扰。
389390

@@ -397,7 +398,7 @@ public class CommandUser extends HystrixCommand<String> {
397398

398399
通过刚才的构造函数也能证明:
399400

400-
![](https://ws2.sinaimg.cn/large/006tKfTcgy1ftq4i6xy2qj30uo09adhp.jpg)
401+
![](https://i.loli.net/2019/05/08/5cd1d2b69cd32.jpg)
401402

402403
还要注意的一点是:
403404

@@ -409,4 +410,4 @@ public class CommandUser extends HystrixCommand<String> {
409410

410411
文末的 hystrix 源码:
411412

412-
[https://github.com/crossoverJie/Java-Interview/tree/master/src/main/java/com/crossoverjie/hystrix](https://github.com/crossoverJie/Java-Interview/tree/master/src/main/java/com/crossoverjie/hystrix)
413+
[https://github.com/crossoverJie/Java-Interview/tree/master/src/main/java/com/crossoverjie/hystrix](https://github.com/crossoverJie/Java-Interview/tree/master/src/main/java/com/crossoverjie/hystrix)

0 commit comments

Comments
 (0)