When a new task is submitted in method execute(Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle.

当提交task时,如果当前线程数小于corePoolSize,那么不管当前已创建线程是否处于空闲状态,总会创建一个新线程来处理该task。

Most typically, core and maximum pool sizes are set only upon construction, but they may also be changed dynamically using setCorePoolSize and setMaximumPoolSize.

核心线程数和最大线程数都可以动态调整。

By default, even core threads are initially created and started only when new tasks arrive, but this can be overridden dynamically using method prestartCoreThread or prestartAllCoreThreads. You probably want to prestart threads if you construct the pool with a non-empty queue.

创建ThreadPoolExecutor时,默认情况下,只有当有任务提交时,才会创建核心线程。不过也可以通过prestartCoreThread和prestartAllCoreThreads提前创建线程。当构造ThreadPoolExecutor时,如果使用非空queue,这很有用。

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

如果当前线程数小于corePoolSize,会直接新增一个线程,而不是把任务加到queue中。

A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even if users forget to call shutdown, then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting allowCoreThreadTimeOut(boolean).

如果ThreadPoolExecutor不再被引用并且其没有存活的线程,那么它可以自动关闭,如果有存活的线程,就不会关闭。如果希望线程最终可以关闭,可以设置keep-alive times,并且设置核心线程数为0或者设置allowCoreThreadTimeOut。

线程增加(a)时机:

1. 任务提交时,当前线程数小于corePoolSize

2. 任务提交时,当前线程数小于maximumPoolSize,且任务队列满

3. 任务提交时,ThreadPoolExecutor处于运行状态,任务添加到队列,随后ThreadPoolExecutor变为非运行状态,任务又未从队列移除成功,且当前没有线程存活,创建一个线程处理该任务

4. 任务提交时,ThreadPoolExecutor处于运行状态,任务添加到队列,但之前创建线程全部die,则创建一个线程处理任务

5. 当前线程运行的任务出现异常,线程死掉,创建新线程替换旧线程(线程没有任务(completedAbruptly=false)或死掉时(completedAbruptly=true)会调用processWorkerExit)

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount(); final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
} tryTerminate(); int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false); // a5
}
}

6. setCorePoolSize, prestartCoreThread, prestartAllCoreThreads, ensurePrestart被调用时

任务reject(r)时机:

1. 任务提交时,当前ThreadPoolExecutor不处于运行状态

2. 任务提交时,当前ThreadPoolExecutor处于运行状态,但队列满,且核心线程数达到maximumPoolSize

3. 任务提交时,ThreadPoolExecutor处于运行状态,任务添加到队列,随后ThreadPoolExecutor变为非运行状态,任务从队列移除成功

    public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) // a1
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command); // r2,r3
else if (workerCountOf(recheck) == 0)
addWorker(null, false); // a3,a4
}
else if (!addWorker(command, false)) // a2
reject(command); // r1
}

线程退出时机:

1. 当前线程运行的任务出现异常

2. ThreadPoolExecutor处于shutdown,且队列为空

3. ThreadPoolExecutor处于非运行态和非shutdown态

4. 没有任务时(比如,当前线程数在core和max之间,只有当队列为空时线程才会退出,否则会执行任务到没有任务时退出)

5. setCorePoolSize, allowCoreThreadTimeOut, setMaximumPoolSize, setKeepAliveTime, shutdownNow, shutdown

ThreadPoolExecutor 杂记的更多相关文章

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

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

  2. [Erlang 0118] Erlang 杂记 V

       我在知乎回答问题不多,这个问题: "对你职业生涯帮助最大的习惯是什么?它是如何帮助你的?",我还是主动回答了一下.    做笔记 一开始笔记软件做的不好的时候就发邮件给自己, ...

  3. 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑

    学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...

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

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

  5. ThreadPoolExecutor源码学习(2)-- 在thrift中的应用

    thrift作为一个从底到上除去业务逻辑代码,可以生成多种语言客户端以及服务器代码,涵盖了网络,IO,进程,线程管理的框架,着实庞大,不过它层次清晰,4层每层解决不同的问题,可以按需取用,相当方便. ...

  6. Java 线程 — ThreadPoolExecutor

    线程池 线程池处理流程 核心线程池:创建新线程执行任务,需要获取全局锁 队列:将新来的任务加入队列 线程池:大于corePoolSize,并且队列已满,小于maxPoolSize,创建新的worker ...

  7. Ubuntu杂记——Ubuntu下用虚拟机共享上网

    由于最近把自己电脑环境换成了Ubuntu,但学校的网络是电信的闪讯,大学里用过的人都知道这货有多坑,而且没有Linux客户端,上网都是问题,怪不得国内用Linux的人那么少,特别是高校的学生(让我瞎逼 ...

  8. java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

    转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...

  9. 【JUC】JDK1.8源码分析之ThreadPoolExecutor(一)

    一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...

随机推荐

  1. 安装git出现templates not found的问题

    背景 goods.api需要在新机器上部署,该机器上没有安装git,需要安装git,查询git版本为2.4.5-1.el6 ,使用yum 一顿安装后,执行git clone命令告知warning: t ...

  2. SQL Server数据类型总结

    1.char char [(n)]存储固定长度的非Unicode字符串数据.n定义字符串长度,并且必须是1到8,000之间的值.存储大小为n个字节. 2.varchar varchar [(n | m ...

  3. C#不能捕捉的异常,如AccessViolationException

    在.net的异常机制中,有部分严重的编程错误(系统的某些Corrupted State Exceptions异常)是默认不被用户使用常规的异常捕捉方式捕捉到的. 微软的这种设计方式,是让用户必须处理该 ...

  4. WPF自定义进度条

    <!--进度条 4812--> <LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill" Sta ...

  5. 1087 1 10 100 1000(打表 set 数学)

    1087 1 10 100 1000 题目来源: Ural 1209 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 1,10,100,1000... ...

  6. 【OCP新题库】052最新题库解析-第5题

    5.Which two affect the time taken for instance recovery? A) size of redo logs B) size of UNDO tables ...

  7. Django2.0 URL配置详解

    转自:https://www.cnblogs.com/feixuelove1009/p/8399338.html Django2.0发布后,很多人都拥抱变化,加入了2的行列. 但是和1.11相比,2. ...

  8. Markdown入门简介

    参考 http://sspai.com/25137 作者: Te_Lee 文章来源: 少数派 Markdown入门简介(使用工具Haroopad) 一.使用的工具----haroopad(http:/ ...

  9. delphi 10.2---非常简单的数组用法求和

    unit Unit9; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  10. 我永远喜欢我的偶像 KIKU