一、为什么要实现线程池?
- 线程的创建与销毁对于CPU而言开销较大,通过池化技术可避免重复的创建与销毁线程。
- 方便与线程资源统一管理。
二、几种常见的线程池以及核心参数
不推荐使用Executor创建线程池,线程池维护的队列未指定长度,有内存溢出的风险存在。
一、 线程的核心参数
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心线程数
maximumPoolSize: 最大线程数
keepAliveTime:非核心线程数空闲时间
unit:时间单位
workQueue:存放任务的阻塞队列
threadFactory:使用线程工厂创建线程
handler:线程的拒绝策略
二、几种常用的线程池
- 创建固定大小的线程池
new ThreadPoolExecutor(
nThreads,
nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory) - 创建单线程的线程池
new ThreadPoolExecutor(
1,
1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())); - 创建缓存线程池
new ThreadPoolExecutor(
0,
Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
三、线程的生命周期状态
- 生命周期状态
Running:可接受新的任务,并可处理队列中的任务。
ShoutDown:不接受新的任务,任然会处理处于队列中的任务。
Stop:不接受新的任务也不会处理队列中的任务,但是不会终止正在执行的任务。
Tidying:不接受新的任务也不处理队列中的任务并且会立即终止正在执行的任务。
Terminated:终止状态。
流转图
四、线程池的执行流程
- 执行executor后,任务首先交由核心线程数处理。
- 核心线程数都为非空闲状态,则将任务放入阻塞队列。
- 阻塞队列满了以后,若核心线程数任然为非空闲状态,则创建非核心线程从队列取任务执行。
- 当核心线程数与非核心线程都处于工作状态中,则执行拒绝策略。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。