三大方法
Executors.newSingleThreadExecutor(); // 单个线程
Executors.newFixedThreadPool(5); // 固定的线程池大小
Executors.newCachedThreadPool(); // 可伸缩的
以上底层都是由 ThreadPoolExecutor 实现
阿里开发手册:线程池不允许使用 Executors 去创建, 而是通过 ThreadPoolExecutor 的方式, 这样的处理方式让写的同学更加明确线程池的运行规则, 规避资源耗尽的风险。
Executors 返回的线程池对象的弊端如下:
- FixedThreadPool 和 SingleThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
- CachedThreadPool:允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
- ScheduledThreadPool:允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
七大参数
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit, // TimeUnit.SECONDS
BlockingQueue<Runnable> workQueue, // new LinkedBlockingDeque<>(3)
ThreadFactory threadFactory, // Executors.defaultThreadFactory()
RejectedExecutionHandler handler // new ThreadPoolExecutor.AbortPolicy()
)
四种策略
- AbortPolicy 如果线程池拒绝了任务,直接报错
- CallerRunsPolicy 线程池让调用者去执行
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run(); // 可以看见源码逻辑为,先判断线程池还未关闭,然后直接r.run运行了任务。
}
}
}
- DiscardPolicy 如果线程池拒绝了任务,直接丢弃
- DiscardOldestPolicy 如果线程池拒绝了任务,直接将线程池中最旧的,未运行的任务丢弃,将新任务入队