线程池创建
public ThreadPoolExecutor(int corePoolSize,//线程池核心线程数(平时保留的线程数)
int maximumPoolSize, //线程池最大线程数
long keepAliveTime, //超出corePoolSize数量的线程的保留时间。
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue,//阻塞队列,存放来不及执行的线程
ThreadFactory threadFactory,
RejectedExecutionHandler handler)//拒绝策略
RejectedExecutionHandler拒绝策略
- AbortPolicy:(默认)丢弃任务,直接抛出RejectedExecutorException异常
- DiscardPolicy:丢弃任务,不抛异常
- DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
- CallerRunsPolicy:用调用者的线程执行该任务
线程池工作原理
execute方法执行逻辑
- 如果当前运行的线程少于corePoolSize,则会创建新的线程来执行当前任务
- 如果运行的线程个数等于或大于corePoolSize,则会提交到阻塞队列workQueue中
- 如果当前workQueue队列已满的话并且没有达到maximumPoolSize,则会创建新的线程执行当前任务
- 如果线程个数已经超过了maximumPoolSize,则会使用拒绝策略RejectedExecutionHandler来进行处理
线程池关闭
关闭线程池,可用过shutdown和shutdownNow两个方法
原理:遍历线程池中所有的线程,然后依次中断
- shutdownNow首先将线程池的状态设置为STOP,然后尝试停止所有正在执行和未执行任务的线程,并返回等待执行任务的列表
- shutdown只是将线程池的状态设置为SHUTDOWN状态,然后中断所有没有正在执行任务的线程
常见线程池
- FixedThreadPool 固定个数的线程池,超出的线程会在队列中等待
- CachedThreadPool(弹性缓存线程池,有就用,没有就创建,空闲回收)
- SingleThreadPool(单线程线程池,保证任务的顺序执行)
- ScheduledThreadpool(定时器线程池)
- WorkStealingThreadPool
- Steal,翻译为偷窃,窃取。这里的意思是,如果当前工作线程处理完自己本地任务队列中的任务时,就会去全局队列或者其他工程线程的队列里面查找工作任务,帮助它们完成。
- 利用Work Staling,可以更好实现负载均衡。因为每个工作线程的任务都是不一样的,完成的时间也不一样。
- ForkJoinThreadPool 类似于多线程递归,将大的计算分为多个小计算并分配给多个线程
阿里开发规范明确指出,创建线程、线程池应有明确意义,方便出错时回溯。
public class TimerTaskThread extends Thread{
public TimerTaskThread(){
super.setName("TimerTaskThread");
}
}