文章目录
为什么需要
- 避免反复创建并销毁线程带来的开销问题
- 过多的线程会占用太多内存
好处
- 加快响应速度
- 合理利用cpu和内存,保证系统高效
- 统一管理线程资源
创建和停止线程池
线程池构造函数的参数
参数名 | 类型 | 含义 |
---|---|---|
corePoolSize | int | 核心线程数 |
maxPoolSize | int | 最大线程数 |
keepAliveTime | Long | 保持存活时间 |
workQueue | BlockingQueue | 任务存储队列 |
threadFactory | ThreadFactory | 当线程池需要新的线程时,会使用threadFactory来生成新的线程 |
Handler | RejectedExecutionHandler | 由于线程池无法接受你所提交的任务拒绝策略 |
解释
-
1.keepAliveTime
- 如果线程池当前的线程数多于corePoolSize,那么如果多余的线程空闲时间超过keepAliveTime,他们就会终止
- 工作队列
- 直接交换:SynchronousQueue(简单中转,maxPoolSize要大一些,相当于没有缓冲的)
- 无界队列:LinkedBlockingQueue(设置maxPoolSize没用,OOM异常)
- 有界队列 :ArrayBlockingQueue
线程池的工作流程
- if 线程数 < corePoolSize,即使其他工作线程处于空闲状态,也会创建新线程来运行新任务
- if >= corePoolSize and < maxPoolSize,则将任务放入队列
- if 队列满了 and 线程数 < maxPoolSize,则创建一个新的线程来运行任务
- if 队列已满 and线程数>=maxPoolSize,则拒绝该任务。
注意:当corePoolSize和maximumPoolSize相同时,就可以创建固定大小的线程池。
拒绝策略
1、AbortPolicy
直接抛出异常,阻止线程正常运行。
2、CallerRunsPolicy
如果被丢弃的线程任务未关闭,则执行该线程任务。
3、DiscardOldestPolicy
移除线程队列中最早的一个线程任务,并尝试提交当前任务。
4、DiscardPolicy
丢弃当前线程任务而不做处理
5、自定义拒绝策略
常用的线程池
newCashedThreadPoll
可缓存的线程池、会回收,使用SynChronousQueue
newFixedThreadPoll
固定大小的线程池
newScheduledThreadPool
可做任务调度,定期周期执行任务,使用DelayedWorkQueue
newSingleThreadExcutor
单个线程的线程池
newWorkingStealingPool
足够大小的线程池,适合递归子任务