在谈到线程池时,时常会出现 Executors 的身影。那么它到底是个神马东东,跟线程池又有神马关系,本文结合jdk1.8源码一探究竟。
突然想提个问题,如果没有 Executors ,线程池是不是就玩不转了?
闲言少叙,直奔主题。
进入Executors,类注释的第一句话是真么写的,
Factory and utility methods for Executor...
没贴全,但已经可以明天它的意义。哦,原来它注释一个工具,为诸如Executor等服务的。那么下面我们继续看,这个工具到底能干什么。
查看Executors中的方法,如下图:
Executors.png
我们发现,其中有大量类似于 new * ThreadPool命名方式的方法。这些方法的命名告诉我们,原来Executors是一个用来创建线程池的工具。
Tips:很多面试官会问候选人,您都用过哪些线程池?其实就是在考察Executors类。
简单看一下线程池(ThreadPoolExecutor)中各个参数的意义:
- 任务(青苹果)进入线程池后,开始创建线程。进一个任务,建一个线程,直至达到coreSize(图中假设coreSize=3);
- 第四个任务进入时,会放入队列(queue),直至队列放满(图中假设队列size=10);
- 第14个任务进入时,会接着创建线程,直至达到maximumSize(图中假设maximumSizie=2)。所以当第16个任务进入时,sorry,将会被拒绝。
根据上述描述,解释一下,Executors中new * ThreadPool()。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- 创建线程数量固定的线程池。core=max。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
- 创建只有单个线程的线程池。core=max=1。那么问题来了,既然只要单个线程,为什么不直接创建线程呢?还非要是用线程池!各位可以自己思考一下答案。(我觉得,原因是线程池总的线程会一直存活。而如果单独创建一个线程,任务处理完则灭亡,而线程池中的核心线程数不会。)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- 创建带缓存的线程池。这里的缓存是指,线程只会存活一段时间,线程有存活时间。咱们可以看到,这里core=0,所以没有核心线程。而队列SynchronousQueue又是一个没有容量的队列(自行查询哈,不再本文范围)。所以任务进入只会,只会交给maximum创建出来的线程处理。而maximum的线程又是有存活时间的,由unit与keepalive两个参数控制。这样就起到了缓存线程的作用。
大概就介绍这么多了,其他创建线程池的方式,不是很常用。
As always and let me know what you think, leave the comments below. Bye :)
网友评论