天天看点

线程池的几种创建方式

最近线程池用的比较多,感觉挺有意思。在此记录一下,线程池的创建有4种方式;

1 .Executors.newCachedThreadPool();

构造方法为:

线程池的几种创建方式

可以看到,CachedThreadPool使用的是同步队列SynchronousQueue。该队列不会缓冲元素,有消费时,才会继续添加任务到队列中。所以为了保证线程池的缓冲作用,最大线程数maxPoolSize一般是INTEGER.MAX_VALUE。

官方的注释中注明,该线程池适用于短时间的异步任务较多的场景。核心线程是0,最大线程数量是Integer.MAX_VALUE,实际上就是没有限制,对于空闲超过60秒的线程就会回收掉。由于该线程池内部可以创建很大的线程数量,所以不适用于耗时长,且任务量大的情况。只能是任务量大,不耗时的任务。

2 .Executors.newFixedThreadPool(3);

这种线程池,是一个固定数量的线程池,如例:我们创建了一个线程数量固定为3的线程池,实际上是核心线程为3,最大线程也为3的线程池,由于其内部维护的数据结构为:无界队列LinkedBlockingQueue,所以当任务数量超过我们设定的线程数时,线程池会将任务投递到无界队列中,这个时候一定要控制投递任务的数量。

3 .Executors.newScheduledThreadPool(10);

定时的线程池,内部维护的是一个延迟工作队列,可以延迟执行任务,或者每隔一段时间执行一个任务。该线程池的keepAliveTime为0L,意思是:只要线程工作完,立马就会被回收,不会有空闲时间。

4 .Executors.newSingleThreadExecutor();

顾名思义,就是创建一个单线程的连接池,细心的朋友会想,这种构造方式和

new FixedThreadPool(1)有什么区别呢?

根据官方注释上说,两者的区别是:后者可以重新构造核心线程的数量,但是前者不行。意思就是FixedThreadPool构造完成后可以设置核心线程的数量,但是singleThreadExecutor不行。我自己试了一下,确实是如此。SingleThreadExecutor不能重新构造核心线程的原因:根据源码看,是因为被FinalizableDelegatedExecutorService包了一层。不能强转成ThreadPoolExecutor,所以不能重新设置核心线程。

继续阅读