newFixedThreadPool:使用LinkedBlockingQueue
实现,定长线程池。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newSingleThreadExecutor:使用LinkedBlockingQueue
实现,一池只有一个线程。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newCachedThreadPool:使用SynchronousQueue
实现,变长线程池。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
线程池的拒绝策略
- AbortPolicy:默认的策略,直接抛出
RejectedExecutionException
异常,阻止系统正常运行。 - CallerRunsPolicy:既不会抛出异常,也不会终止任务,而是将任务返回给调用者。
- DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交任务。
- DiscardPolicy:直接丢弃任务,不做任何处理。
实际创建线程池中单一、可变、定长都不用!因为底层阻塞队列是用LinkedBlockingQueue
实现的, 这个队列默认使用Integer.MAX_VALUE
, 会导致内存溢出, 所以需要自己创建线程池
ExecutorService threadPool = new ThreadPoolExecutor(
2, //核心线程数
5, //最大线程数
1L, //空闲线程存活时间
TimeUnit.SECONDS, //存活时间单位
new LinkedBlockingQueue<>(3), //阻塞队列
Executors.defaultThreadFactory(), //创建线程的工厂类
new ThreadPoolExecutor.CallerRunsPolicy() //拒绝策略
);