线程池核心类
1.在java.util.concurrent包中我们能找到线程池的定义,其中ThreadPoolExecutor是我们线程池核心类,首先看看线程池类的主要参数有哪些
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;
}
1.corePoolSize:核心线程数
2.maximumPool:最大线程数
3.keepAliveTime:当前线程大于核心线程数时,多余的线程会在多长时间后背销毁
4.TimeUnit:keepAliveTime的单位
5.threadFactory:创建线程池的工厂,一般都默认
6.workQueue:任务队列,添加到线程未被执行的任务队列
7.handler:拒绝策略
workQueue分类
1.SynchronousQueue:直接提交队列,每提交一个任务都会阻塞,需要执行删除操作才会被唤醒。此队列总是会马上提交如果有空闲线程会复用空闲线程,如果没有超过最大线程则会开启新线程去执行,否则会拒绝策略
2.ArrayBlockingQueue:有界队列,如果有新的任务添加,线程池会创建新线程去执行,如果达到的核心线程会放到任务队列中,如果任务队列满了会开启线程去执行,如果达到最大线程,则会执行拒绝策略
3.LinkedBlockingQueue:无界队列,如果有新的任务添加,线程池会创建新线程去执行,如果达到了核心线程数会放到任务队列中,maximumPoolSize会无效
4.PriorityBlockingQueue:特殊的无界队列,带有优先级,一般的无界队列都是先进先出,这个则有优先级
拒绝策略分类
AbortPolicy策略:该策略直接拒绝,抛出异常,阻止正常的工作
CallerRunsPolicy策略:如果线程池达到上限,会把任务放到调用者线程中去执行
DiscardOldestPolicy策略: 丢弃队列中最老的那个任务(最先被添加到队列中的任务,再次尝试提交)
DiscardPolicy策略:丢弃无法执行的任务,默认策略
自定义策略:
注意:submit()和execute()区别,submit里面还是调用execute()去执行任务,submit方法对任务进行了封装,返回Feture
线程池的分类
缓存线程池:Executors.newCachedThreadPool = hreadPoolExecutor(0,Integer.maxValue,60L,TimeUnit.Seconds,new SynchronousQueue()); 线程池不会把任务存放到队列中,有任务会开启新的线程去执行任务
定长任务线程:Executors.newFixedThreadPool(4) = ThreadPoolExecutor(4,4,0L,TimeUnit.Seconds,new LinkedBlockingQueue());线程池线核心线程数和最大线程数一样,这些线程不会被回收,超过核心线程数会一直往对垒中添加
单例线程池:Executors.newSingleThreadExecutor()=ThreadPoolExecutor(1,1,0L,TimeUnit.Seconds,new LinkedBlockingQueue());线程池中一共有一个线程,有任务添加时会一直往任务队列中添加,然后顺序执行
周期线程池:newScheduledThreadPool = new ScheduledThreadPoolExecutor(coreSize)
super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS new DelayedWorkQueue());类似于timer,核心线程数是固定的,非核心线程数会被回收