看两段源码:

  1 public ThreadPoolExecutor(int corePoolSize,
2
3 int maximumPoolSize,
4
5 long keepAliveTime,
6
7 TimeUnit unit,
8
9 BlockingQueue<Runnable> workQueue,
10
11 ThreadFactory threadFactory,
12
13 RejectedExecutionHandler handler) {
14
15 if (corePoolSize < 0 ||
16
17 maximumPoolSize <= 0 ||
18
19 maximumPoolSize < corePoolSize ||
20
21 keepAliveTime < 0)
22
23 throw new IllegalArgumentException();
24
25 if (workQueue == null || threadFactory == null || handler == null)
26
27 throw new NullPointerException();
28
29 this.acc = System.getSecurityManager() == null ?
30
31 null :
32
33 AccessController.getContext();
34
35 this.corePoolSize = corePoolSize;
36
37 this.maximumPoolSize = maximumPoolSize;
38
39 this.workQueue = workQueue;
40
41 this.keepAliveTime = unit.toNanos(keepAliveTime);
42
43 this.threadFactory = threadFactory;
44
45 this.handler = handler;
46
47 }
48
49 private boolean addWorker(Runnable firstTask, boolean core) {
50
51 retry:
52
53 for (;;) {
54
55 int c = ctl.get();
56
57 int rs = runStateOf(c);
58
59     // Check if queue empty only if necessary.
60
61 if (rs >= SHUTDOWN &&
62
63 ! (rs == SHUTDOWN &&
64
65 firstTask == null &&
66
67 ! workQueue.isEmpty()))
68
69 return false;
70
71 for (;;) {
72
73 int wc = workerCountOf(c);
74
75 if (wc >= CAPACITY ||
76
77 wc >= (core ? corePoolSize : maximumPoolSize))
78
79 return false;
80
81 if (compareAndIncrementWorkerCount(c))
82
83 break retry;
84
85 c = ctl.get(); // Re-read ctl
86
87 if (runStateOf(c) != rs)
88
89 continue retry;
90
91     // else CAS failed due to workerCount change; retry inner loop
92
93 }
94
95 }
96
97 boolean workerStarted = false;
98
99 boolean workerAdded = false;
100
101 Worker w = null;
102
103 try {
104
105 w = new Worker(firstTask);
106
107     final Thread t = w.thread;
108
109 if (t != null) {
110
111     final ReentrantLock mainLock = this.mainLock;
112
113 mainLock.lock();
114
115 try {
116
117 // Recheck while holding lock.
118
119 // Back out on ThreadFactory failure or if
120
121 // shut down before lock acquired.
122
123 int rs = runStateOf(ctl.get());
124
125 if (rs < SHUTDOWN ||
126
127 (rs == SHUTDOWN && firstTask == null)) {
128
129 if (t.isAlive()) // precheck that t is startable
130
131 throw new IllegalThreadStateException();
132
133 workers.add(w);
134
135 int s = workers.size();
136
137 if (s > largestPoolSize)
138
139 largestPoolSize = s;
140
141 workerAdded = true;
142
143 }
144
145 } finally {
146
147 mainLock.unlock();
148
149 }
150
151 if (workerAdded) {
152
153 t.start();
154
155 workerStarted = true;
156
157 }
158
159 }
160
161 } finally {
162
163 if (! workerStarted)
164
165 addWorkerFailed(w);
166
167 }
168
169 return workerStarted;
170
171 }

以上可以看出,ThreadPoolExecutor的主要参数有:corePoolSize , maximumPoolSize , keepAliveTime ,workQueue,threadFactory,handler ,对于几个参数,我们该如何理解呢?

先看看这几个参数:

corePoolSize :

顾名思义,核心线程大小,即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程;

maximuxPoolSize :

线程池中允许创建的最大线程数大小;

poolSize :

当前线程池中线程的数量,当改值为0的时候,意味着没有任何线程,线程池会终止;同时,poolSize不会超过maximumPoolSize;

看看官方解释:

Queuing

Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:

● If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.

● If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.

● If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

理解:

1、如果当前线程池的线程数还没有达到核心线程数大小,即 poolSize < corePoolSize ,无论是否有空闲的线程,系统回新增一个线程来处理新提交的任务;

2、如果当前线程池的线程数大于或者等于核心线程数大小,即 poolSize >= corePoolSize,且任务队列未满时,将提交的任务提交到阻塞队列中,等待处理workQueue.offer(command);

3、如果当前线程池的线程数大于或者等于核心线程数大小,即 poolSize >= corePoolSize,且任务队列已满时,分以下两种情况:

3.1、poolSize < maximumPoolSize ,新增线程来处理任务;

3.2、poolSize = maximuxPoolSize ,意味中线程池的处理能力已经达到极限,此时会拒绝增加新的任务,至于如何拒绝,取决于RejectedExecutionHandler

ThreadPoolExecutor的corePoolSize、maximumPoolSize和poolSize的更多相关文章

  1. 理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize

    我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...

  2. 线程池的corePoolSize、maximumPoolSize和poolSize

    什么是线程池: 为了避免系统频繁的创建和销毁线程,我们可以将创建的线程进行复用.在线程池中总有那么几个活跃的线程,也有一定的最大值限制,一个业务使用完线程之后,不是立即销毁而是将其放入到线程池中,从而 ...

  3. ThreadPoolExecutor的corePoolSize和maximumPoolSize

    按照JDK文档的描述, 如果池中的实际线程数小于corePoolSize,无论是否其中有空闲的线程,都会给新的任务产生新的线程 如果池中的线程数>corePoolSize and <max ...

  4. ThreadPoolExecutor 入参 corePoolSize 和 maximumPoolSize 的联系

    前言 我们可以通过 java.util.concurrent.ThreadPoolExecutor 来创建一个线程池: new ThreadPoolExecutor(corePoolSize, max ...

  5. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  6. ThreadPoolExecutor源码学习(1)-- 主要思路

    ThreadPoolExecutor是JDK自带的并发包对于线程池的实现,从JDK1.5开始,直至我所阅读的1.6与1.7的并发包代码,从代码注释上看,均出自Doug Lea之手,从代码上看JDK1. ...

  7. Java Executor并发框架(二)剖析ThreadPoolExecutor运行过程

    上一篇从整体上介绍了Executor接口,从上一篇我们知道了Executor框架的最顶层实现是ThreadPoolExecutor类,Executors工厂类中提供的newScheduledThrea ...

  8. [转]ThreadPoolExecutor线程池的分析和使用

    1. 引言 合理利用线程池能够带来三个好处. 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 第 ...

  9. Java 线程池架构原理和源码解析(ThreadPoolExecutor)

    在前面介绍JUC的文章中,提到了关于线程池Execotors的创建介绍,在文章:<java之JUC系列-外部Tools>中第一部分有详细的说明,请参阅: 文章中其实说明了外部的使用方式,但 ...

  10. java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)

    1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /**     * Executes th ...

随机推荐

  1. ef 值转换与值比较器

    前言 简单介绍一下,值转换器和值比较器. 正文 为什么有值转换器这东西呢? 那就是这个东西一直必须存在. 比如说,我们的c# enum 对应数据库的什么呢? 是int还是string呢? 一般情况下, ...

  2. AlertWindowManager 弹出提示窗口

    LookAndFeel(界面外观): NativeStyle:本地化界面为真实用系统内置外观 SkinName:本地化界面(NativeStyle:)设置为假可使用皮肤外观 OptionAnimate ...

  3. ZOS对象存储跨域资源访问的实现和使用

    本文分享自天翼云开发者社区<ZOS对象存储跨域资源访问的实现和使用>,作者:对象存储二三事 跨域的定义 跨域指的是从一个域名去请求另外一个域名的资源,即跨域名请求.跨域时,浏览器不能执行其 ...

  4. .NET最佳实践:webapi返回IAsyncEnumerable提升性能

    什么是IAsyncEnumerable IAsyncEnumerable<T> 是 .NET 中用于表示异步数据流的接口. 它允许你逐个异步地获取数据项,而不是将所有数据一次性加载到内存中 ...

  5. [记录点滴]编译安装luarocks、luacheck、luautf8

    [记录点滴]编译安装luarocks.luacheck.luautf8 0x00 摘要 记录一次安装luarocks&第三方库的过程. 0x01 luarocks 如今每个语言体系中都有一个包 ...

  6. day4-进制与位运算

    进制 对于整数有4种表现方式 二进制,满二进一 十进制,满10进1 八进制,满8进1,数字0开头 十六进制,满16进1,以0x或0X开头 进制转换 二进制转十进制 规则:从最低位开始(右边),将每位数 ...

  7. Manus爆火,是硬核还是营销?

    相信这两天小伙伴们应该被Manus刷屏了,铺天盖地的体验解读文章接踵而来,比如「数字生命卡兹克」凌晨爆肝的热文:「一手体验首款通用Agent产品Manus」.从公众号.朋友圈.抖音.央媒,都能看到Ma ...

  8. 【计算力学】CST单元格式推导

    CST单元格式推导

  9. 错误修正记录:对应的VMware Tools脚本未能成功运行

    起因 装了台式机,想把笔记本里的vmware虚拟机迁移过来:复制过来后开机就出现这种情况,点开机.挂起.关机等操作会报错,然后无法挂起(再点一次就行) 或者使用下方的选项,而非上方包装过的功能,似乎也 ...

  10. Chrome 134 版本新特性

    Chrome 134 版本新特性 一.Chrome 134 版本浏览器更新 1. 在桌面和 iOS 设备上使用 Google Lens 进行屏幕搜索 Chrome 版本 适用平台 发布进度 Chrom ...