Executor中提供的创建线程池的五种方法:
- newFixedThreadPool:
//可重用固定数量的线程池,固定线程数,当线程数大于corePoolSize时,
//将任务放入LinkedBlockingQueue中,当线程池中有空闲线程,会去队列中取任务执行
//创建固定大小的线程池,超出的任务会放入队列,
//弊端:队列任务堆积,会oom 内存溢出
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
- newSingleThreadExecutor:
//有且只有一个线程进行工作,出于任何原因到时失败 会重新创建线程执行
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
- CachedThreadPool
//无界可缓存线程池, maximumPoolSize = 0x7fffffff
//需逻辑控制线程数,否则会一直创建线程处理,知道内存溢出,系统瘫痪
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
/**
pool-1-thread-2---t1
pool-1-thread-4---t3
pool-1-thread-6---t5
pool-1-thread-8---t7
pool-1-thread-10---t9
pool-1-thread-1---t0
pool-1-thread-3---t2
pool-1-thread-5---t4
pool-1-thread-7---t6
pool-1-thread-9---t8
*/
- ScheduledThreadPool
//固定数量线程池,可延迟,定时执行任务
//弊端:队列任务堆积,导致oom 内存溢出
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
- newWorkStealingPool
//没用过
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
这个方法是JDK8中新增加的方法,该方法的内部其实是创建了一个ForkJoinPool,该线程池是搭配着ForkJoinTask来使用的。何谓ForkJoin呢?其实就是分治、合并,把大的任务划分成多个小的子任务然后分别运行最终把结果汇总合并。那何谓WorkStealing呢?这是一种调度策略,其中已完成自己任务的工作线程可以从其他线程窃取挂起的任务,而并不是空闲。该线程池是并行执行,默认并行量是处理器核心数,任务会在多个处理器之间划分。
/**
* ArrayBlockingQueue: 由数组结构组成的有界阻塞队列。
LinkedBlockingQueue: 由链表结构组成的无界阻塞队列,不设置就是最大容量MAX_VALUE = 0x7fffffff。
PriorityBlockingQueue: 支持优先级排序的无界阻塞队列,在内存允许的情况下,会一直添加元素。
DealyQueue: 使用优先级队列实现的无界阻塞延迟队列,只有过期元素才会出队列。
SynchronousQueue: 不存储元素的无界阻塞队列。
LinkedTransferQueue: 由链表结构组成的无界阻塞队列。
LinkedBlockingDeque: 由链表结构组成的双向阻塞队列。
corePoolSize:线程池中持久保持的核心线程数,可通过setCorePoolSize函数动态更改。
runnableTaskQueue:用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列: ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue
maximumPoolSize:线程池允许创建的最大线程数,可通过setMaximumPoolSize函数动态更改
ThreadFactory:用于设置创建线程的工厂。
RejectedExecutionHandler:当队列和线程池都满了,此时无法加入新的任务,线程池饱和。该参数表示饱和策略,默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。
以下是JDK1.5提供的四种策略:AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy
keepAliveTime:默认情况下是指非核心线程变成空闲状态后的存活时间,不影响核心线程,
可通过setKeepAliveTime函数动态更改。++但是可通过调用allowCoreThreadTimeOut函数,来设置该变量对核心线程起作用。
TimeUnit:keepAliveTime的时间单位。
*/