参考文章:https://www.cnblogs.com/dongguacai/p/6030187.html
https://www.cnblogs.com/easycloud/p/3726089.html
线程池的构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
/**
* @param corePoolSize 线程池核心线程数量
* @param maximumPoolSize 线程池最大线程数量
* @param keepAliveTime 当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间
* @param unit 存活时间的单位
* @param workQueue 存放任务的队列
* @param threadFactory 线程工厂
* @param handler 超出线程范围和队列容量的任务的处理程序
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ? null:AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
从以上线程池的构造方法里不难看出,其所有的构造方法实际上都是调用的最后一个构造方法,只是线程工厂和任务处理器的不同而已。
workQueue:存放任务的队列
(1)ArrayBlockingQueue,有界队列。是一种基于数组的有界阻塞队列;
(2)LinkedBlockingQueue,无界队列。是一个基于链表的阻塞队列,吞吐量通常要高于ArrayBlockingQueue, Executors.newFixedThreadPool()使用了这种队列;
(3)SynchronousQueue;直接提交。是一种不存储元素的阻塞队列,每个插入操作必须等另一个线程调用移除操作,否则插入操作一直处于阻塞状态。Executors.newCachedThreadPool使用了这个队列;
(4)PriorityBlockingQueue,是一种具有优先权的阻塞队列,优先级大的任务可以先执行,用户由此可以控制任务的执行顺序。
threadFactory:创建新线程时使用的工厂
(1)Executors.DefaultThreadFactory,将创建一个同线程组且默认优先级的线程;
(2)Executors.PrivilegedThreadFactory,使用访问权限创建一个权限控制的线程。ThreadPoolExecutor默认采用DefaultThreadFactory
handler(饱和策略):超出线程范围和队列容量的任务的处理程序
(1)ThreadPoolExecutor.AbortPolicy(),将抛出RejectedExecutionException异常;
(2)ThreadPoolExecutor.CallerRunsPolicy(),将重试添加当前的任务,重复调用execute()方法;
(3)ThreadPoolExecutor.DiscardOldestPolicy(),将抛弃旧任务;
(4)ThreadPoolExecutor.DiscardPolicy,将直接抛弃任务。ThreadPoolExecutor默认采用AbortPolicy。
线程池原理
一个任务通过execute(Runnable)方法被添加到线程池,任务必须是一个 Runnable类型的对象,任务的执行方法就是调用Runnable类型对象的run()方法。当一个任务通过execute(Runnable)方法欲添加到线程池时,会做一下几步:
-
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
-
如果此时线程池中的数量大于等于corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
-
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理添加的任务。
-
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
-
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
Executors可以创建3种类型线程池
(1)SingleThreadExecutor:单线程线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
(2)FixedThreadExecutor:固定大小线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
(3)CachedThreadPool:无界线程池
ExecutorService threadPool = Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
网友评论