Executors类和ThreadPoolExecutor都是util.concurrent并发包下面的类, Executos下面的newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor、newCachedThreadPool底线的实现都是用的ThreadPoolExecutor实现的,所有ThreadPoolExecutor更加灵活。
ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//空闲存活时间
TimeUnit unit,//单位
BlockingQueue<Runnable> workQueue,//队列
RejectedExecutionHandler handler) {//拒绝策略
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
Executors
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newFixedThreadPool:由参数可以看出,这是创建一个固定大小的线程池,核心线程数和最大线程数一致,LinkedBlockingQueue为无界阻塞队列,意思就是说我最多只能创建固定大小的线程来处理任务,比如核心线程数和最大线程数都为7,但突然来了12个任务,另外5个无法立刻执行,就放到了LinkedBlockingQueue中,如果内存无限大,任务可以是无限多的,newFixedThreadPool中的keepAliveTime、unit都是无意思的,原因最大线程数没有超过核心线程数。
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
newScheduledThreadPool:由参数可以看出, 核心线程数一定,最大线程数很大,队列为优先级队列(不清楚的可以看下,https://blog.csdn.net/wo541075754/article/details/51556198),此线程池可以做定时执行。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newSingleThreadExecutor:由参数可以看出, 核心线程数和最大线程数都是1,LinkedBlockingQueue为无界阻塞队列,也就是说是中只有一个线程在执行,来了再多个任务都得等,等线程执行完上个任务,再去执行下个任务。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
newCachedThreadPool:由参数可以看出, 核心线程数为0,最大线程数很大,队列为无界阻塞队列,空闲存活时间为60秒,意思就是说,来个任务,如果没有空闲的线程,就创建个线程,如果有空闲的线程,就要空闲的线程。
自定义ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//空闲存活时间
TimeUnit unit,//单位
BlockingQueue<Runnable> workQueue,//队列
RejectedExecutionHandler handler) {//拒绝策略
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
有界队列:根据上面参数可知,当队列为有界队列时,
corePoolSize<maximumPoolSize ,BlockingQueue满了,线程池会创建新的线程,直到maximumPoolSize 也满了,如果超过maximumPoolSize就会触发 RejectedExecutionHandler 拒绝策略,一般是CallerRunsPolicy(只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。)策略,或是自定义自己的拒绝策略,自定义拒绝策略实现RejectedExecutionHandler接口,重写rejectedExecution方法。
corePoolSize<maximumPoolSize ,BlockingQueue满了,线程池会创建新的线程,直到maximumPoolSize 没满,没有触发拒绝策略,过了一段时间,任务减少了,一些线程空闲时间超过了keepAliveTime,就会被移除。
corePoolSize=maximumPoolSize ,BlockingQueue满了,如果超过maximumPoolSize就会触发 RejectedExecutionHandler 拒绝策略。
无界队列:
corePoolSize<maximumPoolSize,队列一直不会满(理想情况下),不会触发拒绝策略,如果一段时间没有任务时线程闲置时间超过keepAliveTime,会被移除线程池。
corePoolSize=maximumPoolSize,队列一直不会满(理想情况下),不会触发拒绝策略,如果一段时间没有任务时线程闲置时间超过keepAliveTime,不会被移除线程池。