Java笔记(九):线程池

发布时间 2023-05-26 17:21:17作者: Bota5ky

三大方法

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 如果线程池拒绝了任务,直接将线程池中最旧的,未运行的任务丢弃,将新任务入队