[TOC]
<br/>
> ### 线程池实现原理
![](https://i.loli.net/2019/03/11/5c85d923986ec.png)
![](https://i.loli.net/2019/03/11/5c85da86c5b37.png)
* `ThreadPoolExecutor`执行情况
* 1)如果当前运行的线程少于`corePoolSize`,则创建新线程来执行任务(注意,执行这一步骤需要获取全局锁)。
* 2)如果运行的线程等于或多于`corePoolSize`,则将任务加入`BlockingQueue`。
* 3)如果无法将任务加入`BlockingQueue`(队列已满),则创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)。
* 4)如果创建新线程将使当前运行的线程超出`maximumPoolSize`,任务将被拒绝,并调用`RejectedExecutionHandler.rejectedExecution()`方法。
<br/>
> ### 线程池参数
```
public ThreadPoolExecutor (int corePoolSize, //核心线程数
int maximumPoolSize, //线程池中允许的最大线程数
long keepAliveTime, //线程池中空闲线程所能允许的最长时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //任务的阻塞队列
RejectedExecutionHandler handler) //线程池满时对于提交任务的策略
```
<br/>
> ### 线程池满时的拒绝策略`RejectedExecutionHandler `
* `AbortPolicy`:直接抛出异常(默认)。
* `CallerRunsPolicy`:只用调用者所在线程来运行任务。
* `DiscardOldestPolicy`:丢弃队列里最近的一个任务,并执行当前任务。
* `DiscardPolicy`:不处理,丢弃掉。
<br/>
> ### 向线程池提交的任务类型
* `execute()`方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
* `submit()`方法用于提交需要返回值的任务。线程池会返回一个`future`类型的对象,通过这个`future`对象可以判断任务是否执行成功,并且可以通过`future`的`get()`方法来获取返回值,`get()`方法会阻塞当前线程直到任务完成。
<br/>
> ### `FixedThreadPool`
```
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
```
* `FixedThreadPool`固定线程数的线程池,`corePoolSize`和`maximumPoolSize`都被设置为创建`FixedThreadPool`时指定的参数`nThreads`。
* 当线程池中的线程数大于`corePoolSize`时,`keepAliveTime`为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程将被终止。这里把`keepAliveTime`设置为0L,意味着多余的空闲线程会被立即终止。
* 使用`FixedThreadPool`时,`keepAliveTime`和`RejectedExecutionHandler`均无效。
* `FixedThreadPool`使用无界队列`LinkedBlockingQueue`作为线程池的工作队列,注意:当线程池中的线程阻塞时,新任务不断的添加到无界队列`LinkedBlockingQueue`中,任务的添加速度大于线程池的处理速度,任务队列会越来越长,会造成内存被这个队列撑满。
![](https://i.loli.net/2019/03/11/5c85dfb84ea23.png)
> ### `SingleThreadExecutor`
```
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
```
* `SingleThreadExecutor`是使用单个`worker`线程的`Executor`。
* `SingleThreadExecutor`的`corePoolSize`和`maximumPoolSize`被设置为1。其他参数与`FixedThreadPool`相同。`SingleThreadExecutor`使用无界队列`LinkedBlockingQueue`作为线程池的工作队列。
![](https://i.loli.net/2019/03/11/5c85e98350e00.png)
> ### `CachedThreadPool`
```
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
```
* `CachedThreadPool`的`corePoolSize`被设置为0,即corePool为空;`maximumPoolSize`被设置为`Integer.MAX_VALUE`,即`maximumPool`是无界的。这里把`keepAliveTime`设置为60L,意味着`CachedThreadPool`中的空闲线程等待新任务的最长时间为60秒,空闲线程超过60秒后将会被终止。
* `CachedThreadPool`使用没有容量的`SynchronousQueue`作为线程池的工作队列,但`CachedThreadPool`的`maximumPool`是无界的。这意味着,如果主线程提交任务的速度高于`maximumPool`中线程处理任务的速度时,`CachedThreadPool`会不断创建新线程。极端情况下,`CachedThreadPool`会因为创建过多线程而耗尽CPU和内存资源。
![](https://i.loli.net/2019/03/11/5c85ea527de2c.png)
> ### ` ScheduledThreadPoolExecutor`
* `ScheduledThreadPoolExecutor`继承自`ThreadPoolExecutor`。它主要用来在给定的延迟之后运行任务,或者定期执行任务。
* `DelayQueue`是一个无界队列
![](https://i.loli.net/2019/03/11/5c85ebac87ccd.png)
- asD
- Java
- Java基础
- Java编译器
- 反射
- collection
- IO
- JDK
- HashMap
- ConcurrentHashMap
- LinkedHashMap
- TreeMap
- 阻塞队列
- java语法
- String.format()
- JVM
- JVM内存、对象、类
- JVM GC
- JVM监控
- 多线程
- 基础概念
- volatile
- synchronized
- wait_notify
- join
- lock
- ThreadLocal
- AQS
- 线程池
- Spring
- IOC
- 特性介绍
- getBean()
- creatBean()
- createBeanInstance()
- populateBean()
- AOP
- 基本概念
- Spring处理请求的过程
- 注解
- 微服务
- 服务注册与发现
- etcd
- zk
- 大数据
- Java_spark
- 基础知识
- Thrift
- hdfs
- 计算机网络
- OSI七层模型
- HTTP
- SSL
- 数据库
- Redis
- mysql
- mybatis
- sql
- 容器
- docker
- k8s
- nginx
- tomcat
- 数据结构/算法
- 排序算法
- 快排
- 插入排序
- 归并排序
- 堆排序
- 计算时间复杂度
- leetcode
- LRU缓存
- B/B+ 树
- 跳跃表
- 设计模式
- 单例模式
- 装饰者模式
- 工厂模式
- 运维
- git
- 前端
- thymeleaf
- 其他
- 代码规范
- work_project
- Interview