背景
在上篇文章中java多线程:线程池的深度理解中,我们利用继承ThreadPoolExecutor类完成了线程池的创建。在JDK1.5以后增加了Executors类,该类提供了几种创建线程池的静态方法,比如:
但我们翻阅阿里java开发手册:文中醒目的用红字标明禁示用Executors创建以下四种类型的线程池。本文将通过对这些类型的线程池进行源码跟踪,逐个解析。
FixedThreadPool
FixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。
跟踪下源码:
- 在静态方法newFixedThreadPool中new 了一个LinkedBlockingQueue对象,
- 而这个LinkedBlockingQueue类的构造函中通过Integer.MAX_VALUE对队列的容量做了无界值的设置
/**
*Executors.java
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
...
/**
*LinkedBlockingQueue.java
*/
/**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
/**
* Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
*
* @param capacity the capacity of this queue
* @throws IllegalArgumentException if {@code capacity} is not greater
* than zero
*/
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
如果队列为无界,也即存储任务的队列中任务会堆积,直至系统OutOfMemeryError。
SingleThreadPool
SingleThreadPool是一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
看下SingleThreadPool的源码:与newFixedThreadPool一样,同样是new 了一个LinkedBlockingQueue对象,通过Integer.MAX_VALUE对队列的容量做了无界值的设置。
/**
*Executors.java
*/
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
...
/**
*LinkedBlockingQueue.java
*/
/**
* Creates a {@code LinkedBlockingQueue} with a capacity of
* {@link Integer#MAX_VALUE}.
*/
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
CachedThreadPool
我们两看CachedThreadPool:CachedThreadPool是大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。
源码如下:
-在newCachedThreadPool静态方法中通过new ThreadPoolExecutor对象,并将线程池的最大线程数通过Integer.MAX_VALUE设置为无界值。
/**
*Executors.java
*/
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
线程池会不断地创建线程执行任务,直到系统报OutOfMemoryError。
ScheduledThreadPool
ScheduledThreadPool是一个定长线程池,支持定时及周期性任务执行。
-通过ScheduledThreadPoolExecutor构造函数将线程最大数目通过Integer.MAX_VALUE设为无界值
同CachedThreadPool 线程池一样,也有可能为导致系统OutOfMemoryError。
/**
*Executors.java
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
....
/**
*ScheduledThreadPoolExecutor.java
*/
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
总结
java新手应该尽量采用ThreadPoolExecutor手工创建线程池,这样处理的方式可以更深入地了解线程池的运行规则。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
序号 | 名称 | 类型 | 备注 |
---|---|---|---|
1 | corePoolSize | int | 线程池的基本大小 |
2 | maximumPoolSize | int | 最大线程池大小 |
3 | keepAliveTime | long | 线程最大空闲时间 |
4 | unit | TimeUnit | 时间单位 |
5 | workQueue | BlockingQueue | 线程等待队列 |
6 | threadFactory | ThreadFactory | 线程创建工厂 |
7 | handler | RejectedExecutionHandler | 拒绝策略 |