java中线程池的创建除了使用ThreadPoolExecutor之外,还可以使用Executors的静态方法来获取不同的线程池。
Executors类
Executors利用工厂模式向我们提供了4种线程池静态实现方式。
- 创建无大小限制的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- 创建固定大小的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- 单线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
- 创建定时调度池
// 开启定时调度池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
/**
* 使用ScheduledThreadPoolExecutor的该方法设置参数
* @param command 要承担的线程任务
* @param initialDelay 入池的线程开启的时间(从入池开始计时)
* @param period 线程再一次启动时间
* @param unit period的单位
**/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
通过使用以上四种静态方法,基本可以实现日程中对线程池的需求但是并不推荐使用,原因是使用Executors创建线程池不会传入线程池具体参数而是使用默认值所以我们常常忽略这些参数,从上面的源码中我们可以看到,Executors的静态方法实际上还是调用的ThreadPoolExecutor来创建线程池,只不过,它将绝大多数参数用默认值代替,而只给我们留下了关心的个别参数。
最近阿里发布的 Java开发手册中强制线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。