java线程池种我常用的创建方法
ExecutorService executor = Executors.newFixedThreadPool(20);
ExecutorService executor = Executors.newCachedThreadPool();
ExecutorService executor = Executors.newSingleThreadExecutor();
newFixedThreadPool
Executors是一个类,里面提供多种比较方便快捷的静态方法操作创建线程池
Executors.newFixedThreadPool(20)
方法里面返回的是一个ThreadPoolExecutor
对象,ThreadPoolExecutor
类继承了AbstractExecutorService
类,而AbstractExecutorService
类又实现了ExecutorService
接口。ThreadPoolExecutor
里面提供了多种构造函数。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newFixedThreadPool
方法的corePoolSize
,maximumPoolSize
参数值是一样的,keepAliveTime
(线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间;默认情况下,该参数只在线程数大于corePoolSize
时才有用)传入的是0,阻塞队列使用的是LinkedBlockingQueue
在线程池中总共设置了有4种阻塞队列
1、ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务;
2、LinkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQuene;
3、SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene;
4、priorityBlockingQuene:具有优先级的无界阻塞队列;
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
进入到ThreadPoolExecutor
类中后,在其构造方法中还会有两个默认的参数创建线程的工厂ThreadFactory
和线程池的饱和策略RejectedExecutionHandler
。
线程的饱和策略也默认有4中
1、AbortPolicy直接抛出异常,默认策略
2、CallerRunsPolicy使用调用者所在的线程来处理任务
3、DiscardOldestPolicy抛弃队列中最靠前的任务,并执行当前的任务
4、DiscardPolicy直接丢弃任务
注:也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如记录日志或持久化存储不能处理的任务。
newCachedThreadPool
Executors.newCachedThreadPool()
里面给ThreadPoolExecutor类传入的参数是核心线程corePoolSize
为0,maximumPoolSize
为整型的最大值,超时时间设置成60s,阻塞队列选用SynchronousQuene
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
newSingleThreadExecutor
newSingleThreadExecutor
初始化的线程池中只有一个线程,如果该线程异常结束,会重新创建一个新的线程继续执行任务,唯一的线程可以保证所提交任务的顺序执行,内部使用LinkedBlockingQueue作为阻塞队列。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}