JDK提供了一些列比较成熟的线程池的管理工具,其中的Executors就是其中的杰出代表, 非常简洁的方法调用,确提供了很好的
线程池功能,很显然任何东西都有其特定的适用场景, Executors特点易于使用,但是它可能对高并发的任务执行的场景,会带来灾难性的问题,这一切也源于它优点。
稍微看一下Executors类就知道, 该类几乎提供了一站式的方法,所有创建线程池方法几乎只需要指定线程池的线程数量就可以很容易的去创建一个应用级的线程池,但是对于一个线程池管理工具而言,这也意味这风险,我们看看其中的一个方法实现,
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
线程池使用的队列是 LinkedBlockingQueue, 默认大小是2^31-1, 如果还明白,先别急,我们分析一下线程池是如何管理线程的就一切明白了
简单流程就是这样,当然实际更复杂, 不过这就够了, 也就是说如果我们不指定队列长度, 大量任务申请执行的时候,会导致队列一直增长,内存资源就会很快消耗, 在高并发的任务执行场景下, 很容易引起系统崩溃,所以一般情况下,需要自己去定制线程池一些基本参数, 譬如核心池线程数量、最大线程池大小、队列大小等,下面是一个简单的示例
final ExecutorService fixedThreadPool = new ThreadPoolExecutor(20, 50, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(100));