CachedThreadPool的创建方式
ExecutorService executorService = Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
SynchronousQueue有2个方法需要注意,put和offer,put方法分情况来说:假设线程A正在waiting 从SynchronousQueue取一个元素,此时put(e),则e会被A接走,put会马上返回;假设没有线程正在waiting从SynchronousQueue取一个元素,此时put(e),则put(e)会阻塞当前的线程。put的特点是如果没有线程在waiting从SynchronousQueue取元素,则put(e)会阻塞当前线程。
offer方法分情况来说:假设线程A正在waiting 从SynchronousQueue取一个元素,此时offer(e),则e会被A接走,offer返回true;假设没有线程正在waiting从SynchronousQueue取一个元素,此时offer(e),则offer(e)不会阻塞当前的线程,会马上返回,且返回false。offer特点是如果没有线程在waiting从SynchronousQueue取元素,则offer(e)不会阻塞当前线程。
JDK的ThreadPoolExecutor的execute方法代码如下(如果不理解,建议先看下JDK中ThreadPoolExecutor的源码,理解工作原理)。如果提交的Runnable执行耗时较长,那么多数情况下没有waiting to receive的线程,所以图1中第二个红框处的workQueue.offer(command) 会马上返回false,所以会进入第三个红框处,即在线程池中新增线程。这就是为什么如果我们提交的Runnable执行耗时较长,则会出现很多的线程,如图2所示。
图1 JDK中ThreadPoolExecutor的execute(...)源码
图2 设置每个Runnable中睡眠700毫秒,则线程池创建了10个线程
使用场景:JDK的注释上说,用于short-lived task,这中线程池我在很多源码中看见过。
缺点:线程池中会出现大量的线程。
(adsbygoogle = window.adsbygoogle || []).push({});