常用线程池
种类:
- newCachedThreadPool :创建可缓存的线程池
- newSingleThreadExecutor :创建单线程的线程池
- newFixedThreadPool :创建固定长度的线程池
- ScheduledThreadPoolExecutor 延迟队列
详情
-
newCachedThreadPool(同步队列:SynchronousQueue 是一个不存储元素的队列,可以理解为队里永远是满的,因此最终会创建非核心线程来执行任务。对于非核心线程空闲60s时将被回收。因为Integer.MAX_VALUE非常大,可以认为是可以无限创建线程的,在资源有限的情况下容易引起OOM异常)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
} -
newFixedThreadPool
当一个任务提交时,首先会创建一个核心线程来执行任务,如果超过核心线程的数量,将会放入队列中,因为LinkedBlockingQueue是长度为Integer.MAX_VALUE的队列,可以认为是无界队列,因此往队列中可以插入无限多的任务,在资源有限的时候容易引起OOM异常,同时因为无界队列,maximumPoolSize和keepAliveTime参数将无效,压根就不会创建非核心线
程(队列oom)。
FixedThreadPool是固定核心线程的线程池,固定核心线程数由用户传入。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
threadFactory);
}
-
newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
threadFactory));
} -
ScheduledThreadPoolExecutor 延迟队列
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
corePoolSize是自己传的,主要不一样的就是 队列使用 DelayedWorkQueue,延迟队列,然后我又看了一下延迟队列的原理。
延迟队列提供的功能是在指定时间点才能获取队列元素的功能,队列最前面的元素是最优先执行的元素。
列举一下使用场景可能能够更加好理解,比如缓存系统的设计,缓存中的对象,指定了过期时间,到了过期时间就需要从缓存中移出;在比如任务调度系统,要准确在任务规定的时间点执行任务。这些场景如果我们不使用延迟队列,就必须不同的遍历所有缓存、任务然后判断是否需要移除缓存、执行任务。
而延迟队列则不需要不停的扫描缓存、任务,它能够实现能够实现在准确的时间点去执行任务。