Skip to content

Commit 5209863

Browse files
author
代码风水师
committed
增加了对线程池参数的讲解
1 parent 701a19d commit 5209863

2 files changed

Lines changed: 115 additions & 45 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
* [Java多线程与并发框 (第 10 篇) 深入理解:CAS](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/CompareAndSwap.md)
4848
* [Java多线程与并发框 (第 11 篇) 深入理解:并发包的基石 -- 队列同步器 AQS](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/AbstractQueuedSynchronizer.md)
4949
* [Java多线程与并发框 (第 12 篇) 深入理解:并发辅助工具类(很好的玩的工具类)](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/ConcurrentHelperUtil.md)
50-
* [Java多线程与并发框 (第 12 篇) 深入理解:线程池](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/ThreadPool.md)
50+
* [Java多线程与并发框 (第 12 篇) 深入理解:线程池参数](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/ThreadPool.md)
5151
* Java多线程与并发框 (第 14 篇) 深入理解:Fork/Join框架
5252
* [Java多线程与并发框 (第 15 篇) 深入理解:原子操作](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/AtomicOperation.md)
5353
* [Java多线程与并发框 (第 16 篇) 深入理解:ThreadLocal](https://github.com/about-cloud/JavaCore/blob/master/resource/markdown/multithreads/ThreadLocal.md)
Lines changed: 114 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,114 @@
1-
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">线程池</h3>
2-
3-
#### interfaces
4-
* Callable
5-
* CompletableFuture.AsynchronousCompletionTask
6-
* Future
7-
* RunnableFuture
8-
* Executor
9-
* **ExecutorService**
10-
* ThreadFactory
11-
12-
#### Classes
13-
* AbstractExecutorService
14-
* Executors
15-
* **ThreadPoolExecutor**
16-
* ThreadPoolExecutor.AbortPolicy
17-
* ThreadPoolExecutor.CallerRunsPolicy
18-
* ThreadPoolExecutor.DiscardOldestPolicy
19-
* ThreadPoolExecutor.DiscardPolicy
20-
21-
#### Enums
22-
* TimeUnit
23-
24-
---
25-
* **ThreadPoolExecutor + ThreadFactory实现线程池**
26-
~~~java
27-
/** 使用 ThreadPoolExecutor 自定义池大小,以免无线占有资源,进而导致OOM问题 */
28-
ExecutorService executorService = new ThreadPoolExecutor(500, 500, 0L, TimeUnit.MILLISECONDS,
29-
new LinkedBlockingDeque<>(10), new ThreadFactory() {
30-
@Override
31-
public Thread newThread(Runnable r) {
32-
Thread t = new Thread(r);
33-
// 自定义线程名称(便于排查错误)
34-
t.setName("xxx线程:" + System.currentTimeMillis());
35-
return t;
36-
}
37-
});
38-
39-
// 使用线程池:用execute() 执行操作
40-
executorService.execute(Runnable command);
41-
42-
// 使用完连接池:shutdown() 关闭连接池
43-
executorService.shutdown();
44-
~~~
1+
<h3 style="padding-bottom:6px; padding-left:20px; color:#ffffff; background-color:#E74C3C;">ThreadPoolExecutor线程池</h3>
2+
3+
线程的创建和销毁都会消耗大量资源,就好像公司每天上午9点工作时就招进一批员工,晚上6点干完活就辞退一批员工,这都会销毁公司大量资源。所以合理利用 “池” 中固定、稳定的线程是非常有必要的。
4+
5+
### 扩展关系
6+
7+
![ThreadPoolExecutor继承关系](https://i.loli.net/2018/12/12/5c1070e4ab3ca.png)
8+
9+
#### ThreadPoolExecutor 构造方法
10+
11+
ThreadPoolExecutor 共有四个构造方法:
12+
13+
```java
14+
ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue<Runnable>)
15+
16+
ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue<Runnable>, ThreadFactory)
17+
18+
ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue<Runnable>, RejectedExecutionHandler)
19+
20+
ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue<Runnable>, ThreadFactory, RejectedExecutionHandler)
21+
```
22+
23+
以最多参数的构造方法为例进行分析:
24+
25+
```java
26+
public ThreadPoolExecutor(int corePoolSize,
27+
int maximumPoolSize,
28+
long keepAliveTime,
29+
TimeUnit unit,
30+
BlockingQueue<Runnable> workQueue,
31+
ThreadFactory threadFactory,
32+
RejectedExecutionHandler handler) {
33+
// 核心线程池不能小于0
34+
if (corePoolSize < 0 ||
35+
// 最大池大小不能小于等于0
36+
maximumPoolSize <= 0 ||
37+
// 最大池大小不能小于核心池大小
38+
maximumPoolSize < corePoolSize ||
39+
// 存活时间不能小于0
40+
keepAliveTime < 0)
41+
// 否则将会抛出 IllegalArgumentException 非法参数异常
42+
throw new IllegalArgumentException();
43+
// 工作队列、线程工厂、拒绝执行的处理策略都不能为空,否则将会排除NPE空指针异常
44+
if (workQueue == null || threadFactory == null || handler == null)
45+
throw new NullPointerException();
46+
this.acc = System.getSecurityManager() == null ?
47+
null :
48+
AccessController.getContext();
49+
this.corePoolSize = corePoolSize;
50+
this.maximumPoolSize = maximumPoolSize;
51+
this.workQueue = workQueue;
52+
this.keepAliveTime = unit.toNanos(keepAliveTime);
53+
this.threadFactory = threadFactory;
54+
this.handler = handler;
55+
}
56+
```
57+
58+
#### ①参数 corePoolSize 核心线程池大小:
59+
60+
> 线程池中一直会存活该大小的线程数,即使是没有工作(任务)需要执行。除非设置 `allowCoreThreadTimeOut``true` ,线程池中的核心线程会超时关闭。
61+
62+
63+
64+
#### ②参数 maximumPoolSize 线程池最大大小:
65+
66+
> 线程池最大允许同时存活的线程的大小。
67+
68+
69+
70+
#### ③参数 keepAliveTime 线程空闲时间:
71+
72+
> 当线程池中的线程空闲时间达到 `keepAliveTime` 时,线程会被销毁,仅保留 `corePoolSize` 大小线程,如果`allowCoreThreadTimeOut``true` ,则线程池中包含核心线程在内空闲线程都会被销毁。
73+
74+
75+
76+
#### ④参数 unit 时间单位:
77+
78+
> `keepAliveTime` 的时间单位(枚举类型)`TimeUnit` ,其可选单位有 `TimeUnit.DAYS` 天、`TimeUnit.HOURS` 小时、`TimeUnit.MINUTES` 分钟、`TimeUnit.SECONDS`秒、`TimeUnitMILLISECONDS.`毫秒、`TimeUnit.MICROSECONDS`微秒、`TimeUnit.NANOSECONDS`纳秒,常用的是秒。
79+
80+
81+
82+
#### ⑤参数 workQueue 任务队列(工作队列、缓存队列):
83+
84+
> 当任务所需的线程数达到核心线程数 `corePoolSize ` 时,新任务会放在工作队列中排队(缓存)等待执行。如果任务所需的线程数达到核心线程数 `corePoolSize ` 时,并且工作队列已满时,并且线程池最大大小 `maximumPoolSize ` 大于 核心线程池大小 `corePoolSize` 时,才会创建新的线程去处理任务。
85+
>
86+
> *经常有个错觉,~~认为当任务所需的线程数达到线程池最大线程数 `maximumPoolSize ` 时,新任务才会进入工作队列~~,这是不对的。
87+
88+
89+
90+
#### ⑥参数 threadFactory 线程工厂:
91+
92+
> 用于创建线程池中线程的工厂。创建线程时,经常会给这一批具有处理相同类型任务的线程命名和线程工厂命名(*线程工厂命名是指给poolName线程池命名,作为线程名称的前缀prefix),以此来标识线程的用处,在分析程序执行信息或排查程序异常问题时,非常有帮助。
93+
94+
95+
96+
#### ⑦参数 handler 拒绝处理策略:
97+
98+
> 线程池拒绝处理任务有一下两者情况:
99+
>
100+
> 1)、当线程池中的线程数达到核心池大小时,并且任务队列已满,会使用拒绝处理策略;(此种情况就像工作台上的工作量积累已满,又没有足够的人员去处理,那么我们就可以拒绝处理新任务。)
101+
>
102+
> 2)、当调用shutdown() 方法后,会等待线程池中正在执行的任务执行完毕,然后再关闭线程池,如果在调用 shutdown() 方法后(还未真正关闭时),紧接着又有新的任务提交时,会使用拒绝处理策略。(此种情况就像工作到了下班时间,工作人员还在忙着手头上剩余的工作,如果此时又新任务提交,那么我们就可以拒绝处理新任务。)
103+
>
104+
> (当然也可以不拒绝)
105+
106+
**拒绝处理策略:**
107+
108+
| 拒绝处理策略 | 是否默认 | 描述 |
109+
| ------------------- | -------- | ---------------------------------------------------- |
110+
| AbortPolicy || 丢弃任务,抛RejectedExecutionException异常; |
111+
| ~~DiscardPolicy~~ | | 直接忽视,也不会抛出异常,不推荐使用; |
112+
| DiscardOldestPolicy | | 从任务队列中踢出最先进入队列(最后一个执行)的任务; |
113+
| CallerRunsPolicy | | 执行新任务。 |
114+

0 commit comments

Comments
 (0)