看两段源码:

  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. linux:计划任务

    at 计划执行一次性任务 at  + time 表示方法: atq  -c:查看目前等待执行的任务 atrm  任务编号 :删除at任务  [root账户才能删除,其他用户只能查询] crontab ...

  2. BUUCTF刷题-Web方向1~5wp

    [极客大挑战 2019]EasySQL 一个sql注入登录框,直接万能密码登录 拿到flag [极客大挑战 2019]Havefun 打开环境,没有任何信息,查看源码,发现这么一段代码 GET方式传入 ...

  3. MacOS修改应用快捷键的一般思路

    具体步骤为: 使用CheatSheet软件查看菜单项名称 在系统设置中修改菜单项的快捷键 举个例子:修改Chrome中左右切换tab的快捷键(系统语言为英文,中文同理) 默认采用Ccontrol Ta ...

  4. linux更新软件源 安装docker

    vim /etc/aptsources.list 学习参考 https://blog.csdn.net/bskfnvjtlyzmv867/article/details/81044217   # 默认 ...

  5. Luogu P11361 NOIP2024 编辑字符串 题解 [ 黄 ] [ 贪心 ]

    编辑字符串:这题能评蓝已经说明了洛谷的唐氏. 结论 找到两个字符串种连续的且可以移动的所有极大子区间,然后线性扫一遍,看这一位所处的子区间中有多少个 \(0\) 和 \(1\),两个都有 \(0\) ...

  6. IAP升级(STM32)

    IAP升级(STM32) IAP作用简述:将要升级的程序bin文件通过串口发送给STM32,STM32接收后存储到FLASH或者SRAM,用户通过事件(按键等)触发(也可延时自动触发)后将升级 文件夹 ...

  7. Shell - [11] 开源Apache Zookeeper集群启停脚本

    一.集群角色部署 当前有Zookeeper集群如下 主机名 ctos79-01 ctos79-02 ctos79-03 Zookeeper ○ ○ ○ 二.脚本使用 三.脚本内容 #!/bin/bas ...

  8. .NET周刊【3月第1期 2025-03-02】

    国内文章 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章 https://www.cnblogs.com/shanyou/p/18737657 2025年2月25日,.NET ...

  9. Golang 入门 : Go语言介绍

    简介 Go 语言又称 Golang,由 Google 公司于 2009 年发布,近几年伴随着云计算.微服务.分布式的发展而迅速崛起,跻身主流编程语言之列,和 Java 类似,它是一门静态的.强类型的. ...

  10. Ubuntu上安装MySQL / MariaDB

    目录 在Ubuntu上安装MySQL 更新Ubuntu 安装MySQL 安全的MySQL 优化MySQL(仅限高级用户) 如何在Ubuntu上安装MariaDB 更新Ubuntu 安装MariaDB ...