很简单,新建线程,60秒空闲后回收,有等待队列,其实就是比你没有用线程池管理多了 一些资 源控制策略,你还可以为不同的业务分配不同的线程池,定义特定的线程池名称,查日志可以更 加方便
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue
}
从ThreadPoolExecutor构造方法的参数可以看出:
很简单,新建线程,60秒空闲后回收,有等待队列,其实就是比你没有用线程池管理多了一些资 源控制策略,你还可以为不同的业务分配不同的线程池,定义特定的线程池名称,查日志可以更 加方便
该类型线程池有0个核心线程,但却不限制最大线程的数量(可达到Integer.MAX_VALUE个)。 如果线程闲置的时间超过一定的时间60s,则被终止并移出缓存。所以即使长时间闲置,这种 线程池也不会消耗什么资源。
所以该类型线程池适用于场景:比较适合处理大量短时间的工作任务。
比较有意思的是,最后一个参数用的是SynchronousQueue,而不是常用的
LinkedBlockingQueue,这是为什么呢?
这需要我们对SynchronousQueue有一定的了解:
SynchronousQueue从真正意义上来说并不能算是一个队列,将其理解为一个用于线程之间通 信的组件更为恰当。SynchronousQueue没有容量的概念,当一个线程在执行完入队列操作之 后,必须等待另外一个线程与之匹配完成出队列后方可继续再次入队列。
正因为SynchronousQueue队列没有容量,不能存放任务,所以当有一个任务过来,此时没有 空闲线程,就会去创建新线程。从下面的源码中可以验证:
if (command == null)
throw new NullPointerExceptionO ;
int c = ctl.get();
if(workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//SynchronousQueue的offer方法会返回false,跳过该判断
if (isRunning(c) && workQueue.offer (command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//直接addWorker,创建新线程
else if (!addWorker(command, false))
reject(command);
}
Was this helpful?
0 / 0