线程池,其实就是一个线程的缓冲池。它可以有效的降低创建、销毁线程的开销。维护一些线程在线程池内,方便使用。
线程池的核心参数:
我们举一个栗子:
假如一家工厂有一条生产线,从人才市场聘请了5个正式工人来生产商品,刚开始工人够用,每天生产商品,但过了3个月后,订单越来越多,工人已经忙不过来了,排队的订单已经堆积在仓库了,这个时候厂长又赶紧到人才市场临时聘请了5个工人,一起生产,但又过了3个月,排队的订单越来越多,厂长就拒绝了后续进来的订单,又从人才市场聘请了5个临时工人,效率提高了之后,仓库里的订单也慢慢消化掉了,过了1个月所有订单都生产完毕了,厂长留了这10个临时工1个月,以防止订单过剩的情况,1个月过后,这10个人也离职了,工厂继续靠5个正式工人进行生产。
在这个例子当中,正式工人就相当于corePoolSize
正式工人 + 临时工人相当于maximumPoolSize
留下临时工人一个月,防止订单过量就像当于keepAliveTime
仓库就相当于workQueue
人才市场就相当于threadFactory
拒绝后续订单就相当于RejectedExecutionHandler
也就是说你定义了一个线程池,那么corePoolSize就相当于你的线程池有多少条正式线程,来接收外部提供进来的任务,当所有正式线程都在工作时,如果外部还提交任务到线程池,那么就会进入等待队列,直到队列也满了之后,就会开启临时线程去处理队列中的任务,临时线程的最大数就是maximumPoolSize - corePoolSize的数量,等到线程池内线程数量满了之后,如果外部还有任务提交进来,就是使用RejectedExecutionHandler来拒绝提交进来的任务,等临时线程工作完毕后,线程池会维护到它的存活时间完毕后再销毁临时线程。而在这个例子当中,所有的线程都是通过threadFactory来创建的。
以上就是线程池所有参数的详解。
不同类型的RejectedExecutionHandler:
AbortPolicy: 当核心数、最大数、队列都已经满了的时候,采用此策略,会直接抛出RejectedException。
DiscardPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会放弃掉刚刚提交的任务。
DiscardOldestPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会放弃掉队列最前面的任务。
CallerRunsPolicy:当核心数、最大数、队列都已经满了的时候,采用此策略,会在提交此任务的线程上执行任务。
我们来看一下Java已经为我们准备好的线程池类
1. CachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
CacheThreadPool(缓存线程池):
该线程池内所有的线程都为临时线程,最大维护线程数为Integer.MAX_VALUE,存活时间为1分钟,提交进来一个任务,就开启一个线程去执行,执行完毕后维护1分钟。
2. FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
FixedThreadPool(固定线程池):
该线程池内核心数和最大数一致,提交任务就开启线程执行,线程完毕后不缓存。
3. SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
该线程池只缓存一个线程去执行。
4. ScheduledThreadPool(周期性执行线程池):
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
该线程池周期性执行任务,类似于Timmer