线程池可以广泛的应用于同步或者异步处理的场景中,线程池主要的核心思想是能够帮助我们将`任务的提交`和任务的`执行`分离开来,在JVM的线程和操作系统的线程之间又多封装了一层(主要用Executor框架实现)。让开发人员不用显示的去创建线程(阿里开发手册就明确说明不能手动创建线程!)
使用线程池带来的三个好处:
1. 降低资源消耗:可以重复利用创建的线程来执行任务。
2. 提高响应速度:当有大量的任务到达时,可以立刻处理任务,而不用等到线程创建才被执行(并不一定,还是得看具体的线程池的实现细节和任务量)。
3. 提高线程的可管理性。
当向一个线程池提交一个任务(Task)之后,其处理流程如下:
![](https://img.kancloud.cn/69/b8/69b8c6fabcb4c2e5cb9d49808b9090e6_1032x325.png)
主要概念:
1. 核心线程池:在创建线程池的时候会让我们设置核心线程池中允许的线程数量的大小,线程池优先使用核心线程处理任务。
2. 工作队列:用来存放要执行的任务,线程池中的线程可以从工作队列中获取任务来执行。
3. 饱和策略:当工作队列和线程池运行的最大线程都已经满的时候,证明线程池无法再处理更多的任务了,此时需要制定一些策略来对新到来的数据进行处理。
其创建流程如下:
1. 对于一个新添加的任务,当核心线程没有满的时候,创建新的核心线程来执行该任务。(会阻塞获取全局锁)
2. 当核心线程已满的时候,将尝试将任务放入阻塞队列中。
3. 如果阻塞队列已满,如果当前线程池中的线程数还没有到达最大线程数,则会创建新的线程执行任务。
4. 如果线程数达到最大线程数,则会触发拒绝策略。根据不同的拒绝策略对任务进行处理。
### 线程池的创建
Java中使用ThreadPoolExecutor类来表示一个线程池:
```java
new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler
);
```
参数的含义:
1. corePoolSize:核心线程池的大小,当提交一个任务的时候,核心线程池会创建一个线程来执行任务;即使是核心线程池中有空闲的线程也会创建新的线程,直到任务的数量大于corePoolSize。如果要提前创建所有的线程可以使用:prestartAllCoreThread();
2. maximunPoolSize:线程池允许的最大线程数量(包括核心线程数)。如果工作队列已经满了,并且已经创建的线程数量小于该值,线程池就会创建新的线程对象。`设置了无界的工作队列,该参数就不起作用了。`
3. keepAliveTime:线程空闲时的存活时间,如果任务时间比较短可以设置大一点。
4. unit:存活时间单位。
5. workQueue:工作队列,用于保存等待执行的任务的阻塞队列,所谓阻塞队列就是获取或者添加数据的时候可能进行阻塞,有如下几种可以选择:
* ArrayBlockingQueue:数组结构的`有界`队列,按照先进先出的方式工作。
* LinkedBlockingQueue:链表结构的*无界*队列(最大值为Integer.MAX\_VALUE),按照先进先出的方式工作,吞吐量要大于ArrayBlockingQueue,Executors.newFixedThreadPool()就是使用这个结构。也可以设定边界。
* SynchronousQueue:不存储元素的阻塞队列,插入操作必须等到另一个线程执行移除操作。吞吐量要大于LinkedBlockingQueue。Executors.newCachedThreadPool使用了这个队列。
* PriorityBlockingQueue:具有优先级的无限阻塞队列。
6. threadFactory:用于设置创建线程的工厂,可以让创建出来的线程的名字更有意义。
7. handler 饱和策略:
- AbortPolicy:直接抛出异常;
- CallerRunsPolicy:只用调用者所在的线程来运行任务;
- DiscardOldPolicy:丢弃队列里最近一个任务,并执行当前任务;
- DiscardPolicy:不处理,丢弃掉。
### Executor框架
在Java中的线程即是工作单元,也是执行机制,在JDK5.0之后将工作单元和执行机制分离开来。工作单元由Runnable和Callable接口表征,执行机制由Executor框架提供。
Executor框架的结构:
1. 需要执行的任务:由Runnable和Callable接口提供。
2. 任务的执行:由Executor接口的关键实现类ThreadPoolExecutor和ScheduledThreadPoolExecutor(即线程池)提供。其中ScheduledThreadPoolExecutor可以在给定的延迟后执行命令,或者定期执行,功能比Timer灵活强大。
3. 异步计算结果:由Future和FutureTask提供。
4. 工厂类:Executors。
通过Executos工具类可以创建三种类型的ThreadPoolExecutor,分别为:
1. 可重用固定线程数的线程池:FixedThreadPool
~~~
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
~~~
特点:
* 核心线程数和最大线程数相同,为指定的参数nThreads。
* 线程空闲就会被终止。
* 使用LinkedBlockingQueue阻塞无界的阻塞队列。
* 不用调用拒绝策略(队列无界)。
2. 使用单个worker线程的线程池:SingleThreadExecutor
~~~
public staitc ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
~~~
特点:
* 只有一个线程。
* 线程空闲就会被终止。
* 使用LinkedBlockingQueue无界队列。
* 不会调用拒绝策略。
3. 根据需要创建线程的线程池:CachedThreadPool
~~~
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
~~~
特点:
* 核心线程数为0,最大线程数为整型的最大值。
* 空闲关闭时间为60s。
* 使用没有长度的阻塞队列SynchronousQueue。
- 第一章 Java基础
- ThreadLocal
- Java异常体系
- Java集合框架
- List接口及其实现类
- Queue接口及其实现类
- Set接口及其实现类
- Map接口及其实现类
- JDK1.8新特性
- Lambda表达式
- 常用函数式接口
- stream流
- 面试
- 第二章 Java虚拟机
- 第一节、运行时数据区
- 第二节、垃圾回收
- 第三节、类加载机制
- 第四节、类文件与字节码指令
- 第五节、语法糖
- 第六节、运行期优化
- 面试常见问题
- 第三章 并发编程
- 第一节、Java中的线程
- 第二节、Java中的锁
- 第三节、线程池
- 第四节、并发工具类
- AQS
- 第四章 网络编程
- WebSocket协议
- Netty
- Netty入门
- Netty-自定义协议
- 面试题
- IO
- 网络IO模型
- 第五章 操作系统
- IO
- 文件系统的相关概念
- Java几种文件读写方式性能对比
- Socket
- 内存管理
- 进程、线程、协程
- IO模型的演化过程
- 第六章 计算机网络
- 第七章 消息队列
- RabbitMQ
- 第八章 开发框架
- Spring
- Spring事务
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 数据库
- Mysql
- Mysql中的索引
- Mysql中的锁
- 面试常见问题
- Mysql中的日志
- InnoDB存储引擎
- 事务
- Redis
- redis的数据类型
- redis数据结构
- Redis主从复制
- 哨兵模式
- 面试题
- Spring Boot整合Lettuce+Redisson实现布隆过滤器
- 集群
- Redis网络IO模型
- 第十章 设计模式
- 设计模式-七大原则
- 设计模式-单例模式
- 设计模式-备忘录模式
- 设计模式-原型模式
- 设计模式-责任链模式
- 设计模式-过滤模式
- 设计模式-观察者模式
- 设计模式-工厂方法模式
- 设计模式-抽象工厂模式
- 设计模式-代理模式
- 第十一章 后端开发常用工具、库
- Docker
- Docker安装Mysql
- 第十二章 中间件
- ZooKeeper