文章目录
1 介绍
Executors,Java并发包中提供了类似于工厂方法的类,用于创建不同的ExecutorService,当然还包括拒绝策略、ThreadFactory等
2 方法
2.1 FixedThreadPool
// 创建ExecutorService,指定核心线程数
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
/ 创建ExecutorService,指定核心线程数和ThreadFactory
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
- 核心线程数和最大线程数是相等的,因此该线程池中的工作线程数将始终是固定的。
- 任务队列为LinkedBlockingQueue(无边界),所以理论上提交至线程池的任务始终都会被执行,只有显式地执行线程池的关闭方法才能关闭线程池。
2.2 SingleThreadPool
/ 创建只有一个工作线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
// 创建只有一个工作线程的线程池,并指定ThreadFactory
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
static class FinalizableDelegatedExecutorService extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
// 重写finalize方法
protected void finalize() {
// 当gc发生的时候,线程池会被执行shutdown
super.shutdown();
}
}
- SingleThreadPool是只有一个核心线程的线程池,
- 但是Finalizable代理了该线程池,因此当线程池引用可被垃圾回收器回收时,线程池的shutdown方法会被执行,当然我们还是建议显式地调用线程池的关闭方法。
2.3 CachedThreadPool
// 创建Cached线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
// 创建Cached线程池并指定ThreadFactory
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
CachedThreadPool根据需要创建新线程,但会重用以前构造的可用线程。该线程池通常会用于提高执行量大的、耗时较短的、异步任务程序的运行性能,在该线程池中,如果有可用的线程将被直接重用。如果没有可用的线程,则会创建一个新线程并将其添加到池中。未被使用且空闲时间超过60秒的线程将被终止并从线程池中移除,因此长时间空闲的线程不会消耗任何资源。
2.4 ScheduledThreadPool
// 构造指定核心线程数的ScheduledThreadPoolExecutor
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
// 指定核心线程数和ThreadFactory
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return
new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
2.5 WorkStealingPool
// 并发度等于CPU核数
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
// 允许指定并发度
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
WorkStealingPool是在JDK1.8版本中引入的线程池,它的返回结果是ForkJoinPool,而不是ScheduledThreadPoolService或ThreadPoolExecutor。
与其他线程池不同的是,WorkStealingPool中的工作线程会处理任务队列中与之对应的任务分片(Divide and conquer:分而治之),如果某个线程处理的任务执行比较耗时,那么它所负责的任务将会被其他线程“窃取”执行,进而提高并发处理的效率。