目录
种类
Executors.newCachedThreadPool
- 定义:无界线程池,可自动回收
- 缺点:涌入大量任务时会大量创建线程
Executors.newFixedThreadPool
- 定义:线程池中的线程数固定大小,超出的线程会在队列中等待
- 缺点:任务数量过大效率不高
Executors.newScheduledThreadPool
- 定义:创建一个定长线程池,支持定时及周期性任务执行
Executors.newSingleThreadExecutor
- 定义:单个后台线程
总结
- 深入源码,你会发现:这几个方法都调用了ThreadPoolExecutor的构造函数,只要研究ThreadPoolExecutor构造函数就行
补充 Executors类创建的线程池对象多有弊端
- FixedThreadPool、SingleThreadPool ,允许阻塞队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
- CachedThreadPool、ScheduledThreadPool,允许创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM 。
区别
- xexecutor.submit()
- xexecutor.execute()
- submit会返回future,可以从中拿到线程执行结果
属性
corePoolSize
- 核心线程数,平时保留的线程数
maximumPoolSize
- 最大线程数,当阻塞队列都放不下时,启动的新线程的最大数量
keepAliveTime
- 超出核心线程数的那些线程,它们的保留时长
unit
- TimeUnit,线程保留时间的单位
workQueue
- BlockingQueue
,阻塞队列,存放来不及执行的线程 - ArrayBlockQueue:构造函数一定要传大小
- LinkedBlockQueue:默认大小为Integer.MAX_VALUE,大量任务会耗尽内存
- SynchronousQueue:同步队列,一个没有存储空间的阻塞队列,将任务交付给工作线程
- PriorityBlockingQueue:优先队列
threadFactory
- ThreadFactory,线程工厂
handler
- RejectedExecutionHandler,饱和策略。
- 理解:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,三者都满了,此时使用handler处理被拒绝的任务
- 策略:见拒绝策略
构造方法
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler){}
拒绝策略
- AbortPolicy(默认):丢弃任务、且抛出异java.util.concurrent.RejectedExecutionException
- CallerRunsPolicy:主线程执行该任务,下一任务继续往线程池中添加(重复此过程)。可有效降低添加线程的速度
- DiscardOldestPolicy:抛弃队列最前面的任务,尝试当前任务(重复此过程)
- DiscardPolicy:丢弃任务,但不抛出异常
实践
springboot配置线程池
@Configuration
public class ThreadPoolTaskConfig {
@Bean
public Executor executor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 可用CPU数量;不小于1
int core = Runtime.getRuntime().availableProcessors();
// 核心线程数
executor.setCorePoolSize(core);
// 最大线程数
executor.setMaxPoolSize(core*2+1);
// 除核心线程外的线程存活时间
executor.setKeepAliveSeconds(3);
// 默认使用SynchronousQueue,若传值>0,底层队列使用LinkedBlockingQueue
executor.setQueueCapacity(40);
// 线程名称前缀
executor.setThreadNamePrefix("-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}