看两段源码:

  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. c++:-6

    上一节学习了C++中的多态性:c++:-5,本节学习C++的函数模版.数据结构以及排序查找操作: 模版 函数模版 思考:如果重载的函数,其解决问题的逻辑是一致的.函数体语句相同,只是处理的数据类型不同 ...

  2. Kotlin:定义参数是函数的函数、函数内联、具名函数的函数引用

  3. 小程序 uni-app动态更改标题

    uni-app动态更改顶部标题 uni-app uni.setNavigationBarTitle({ title: '编辑班级荣誉' }) 小程序 wx.setNavigationBarTitle( ...

  4. 共促数字经济高质量发展,天翼云出席2024 IDC中国年度盛典!

    9月11日,2024 IDC中国年度盛典暨颁奖典礼在上海盛大启幕.本次峰会以「AI时刻,欢迎来到下一个大事件」为主题,汇聚行业专家.意见领袖,深度探讨生成式AI.中国企业出海.创新业务模式.科技可持续 ...

  5. RabbitMQ(八)——消息确认

    RabbitMQ系列 RabbitMQ(一)--简介 RabbitMQ(二)--模式类型 RabbitMQ(三)--简单模式 RabbitMQ(四)--工作队列模式 RabbitMQ(五)--发布订阅 ...

  6. CF935D Fafa and Ancient Alphabet 题解

    讲一个很暴力的方法(为描述方便,下文 \(a\) 数组代表 \(s1\),\(b\) 数组代表 \(s2\)). 发现假如当前 \(a_i\ne b_i\),就不需要再向下枚举了,于是拥有了分类讨论的 ...

  7. Arduino语法--数据类型

    Arduino与C语言类似,有多种数据类型.数据类型在数据结构中的定义是一个值的集合,以及定义在这个值集上的一组操作,各种数据类型需要在特定的地方使用.一般来说,变量的数据类型决定了如何将代表这些值的 ...

  8. PowerJob:一款强大且开源的分布式调度与计算框架

      项目名称:PowerJob 项目作者:假诗人 开源许可协议:Apache-2.0 项目地址:https://gitee.com/KFCFans/PowerJob 项目简介 PowerJob(原Oh ...

  9. MySQL - [11] InnoDB存储引擎

    Page 页.是真正理解InnoDB存储引擎的入口. 一.Page -- 页 1.1.InnoDB 数据页及其结构 为了避免一条一条读取磁盘数据,InnoDB采取页的方式,作为磁盘和内存之间交互的基本 ...

  10. 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理

    在 AI 编程领域国内外有一堆能叫的上号的应用: Cursor Windsurf Trae 阿里的「通义灵码」 百度的「文心快码」 字节跳动的「MarsCode」 科大讯飞的「iFlyCode」 Gi ...