6 种
//创建一个定时任务的线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
//创建单线程的线程池
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
//创建缓存线程池(重用先前的线程)
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//创建一个带有固定线程的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(4);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
顾名思义,就是创建线程数量固定的线程池,线程池的corePoolSize
和maximumPoolSize
大小一样,并且keepAliveTime
为0,传入的队列LinkedBlockingQueue
为无界队列。在说ThreadPoolExecutor
的时候也说过,传入一个无界队列,maximumPoolSize
参数是不起作用的。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
从代码中也能看得出来,corePoolSize
和maximumPoolSize
都是1,keepAliveTime
是0L, 传入的队列是无界队列。线程池中永远只要一个线程在工作。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
可缓存线程池,说道缓存一般离不开过期时间,该线程池也是,corePoolSize
设置为0,maximumPoolSize
设置为int最大值,不同的是,线程池传入的队列是SynchronousQueue
,一个同步队列,该队列没有任何容量,每次插入新数据,必须等待消费完成。当有新任务到达时,线程池没有线程则创建线程处理,处理完成后该线程缓存60秒,过期后回收,线程过期前有新任务到达时,则使用缓存的线程来处理。
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
这个线程池使用了ScheduledThreadPoolExecutor
,该线程池继承自ThreadPoolExecutor
, 执行任务的时候可以指定延迟多少时间执行,或者周期性执行。
创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。线程池中最多执行1个线程,之后提交的线程活动将会排在队列中以此执行并且可定时或者延迟执行线程活动。
JDK8新增,根据所需的并行层次来动态创建和关闭线程,通过使用多个队列减少竞争,底层使用ForkJoinPool来实现。优势在于可以充分利用多CPU,把一个任务拆分成多个“小任务”,放到多个处理器核心上并行执行;当多个“小任务”执行完成之后,再将这些执行结果合并起来即可。