线程池的创建方式
1、通过Executors的静态方法可以创建四种类型的线程池。(不推荐)
1)FixedThreadPool 创建一个固定线程数的线程池,线程数量一直保持固定不变,如果任务提交时,没有空闲线程,那就进入任务队列,当有空闲时间时,再执行任务队列中的任务。
2)SingleThreadExecutor 线程池中始终只有一条线程。
3)CachedThreadPool 根据实际情况调整线程的数量,默认初始为0,当有任务提交时,创建线程去执行,当任务执行完毕,默认空闲等待60秒没有新任务提交就被销毁。
4)ScheduledThreadPool 可以在给定的延迟后或者定时运行任务。
PS:上面四种的任务队列长度最大都是Integer.MAX_VALUE,可能造成大量的请求堆积,从而OOM.
2、使用ThreadPoolExecutor()创建线程池。(推荐)
1)七个参数
corePoolSize 核心线程数,任务队列未到达最大容量时,最大可运行线程数。
maximumPoolSize 最大线程数,任务队列达到最大线程数时,最大可运行线程数。
keepALiveTime 存活时间,核心线程数之外的空闲线程存活时间
unit 时间单位,存活时间的时间单位
workQueue 任务队列,暂存等待执行的任务
threadFactory 线程工厂,用来创建线程,一般使用默认的
handler 拒绝策略,当达到最大线程数并且任务队列达到最大容量时,提交的任务会被拒绝,使用相应的拒绝策略。
PS:
线程池默认线程数量是0,当有任务提交时,会创建线程
当线程数达到核心线程数时,还有任务提交,会被暂存在先入先出的任务队列,保证有序性
当任务队列达到最大容量时,继续创建线程,线程达到最大线程数时,新提交的任务同样会进入任务队列
当任务队列再次达到最大容量时,使用拒绝策略
当线程执行完之后,空闲线程超过设置的存活时间,会被回收,直到线程数减少到核心线程数,回收才会停止
2) 拒绝策略
ThreadPoolExecutor.AbortPolicy: 抛出异常拒绝新任务。
ThreadPoolExecutor.CallerRunsPolicy:使用当前主线程执行新任务,慎选。
ThreadPoolExecutor.DiscardPolicy:直接丢弃新任务。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃最早的新任务,也就是任务队列中最早未被处理的任务。
阻塞队列
LinkedBlockingQueue(基于链表的无界队列)
FixedThreadPool和ISingleThreadExecutor使用的是这种队列,队列最大可以达到Integer.MAX_VALUE,导致OOM。
SynchronousQueue(同步队列)
CacheThreadPool 使用的是这种队列,他不存放元素,当有新任务来时,有空闲线程就是用空闲线程,否则就创建线程,线程数最大也可以达到Integer.MAX_VALUE,导致创建大量的线程,导致OOM。
DelayedworkQueue(延迟阻塞队列)
ScheduleThreadPool使用这种线程,内部元素会按照定时时间先后排序,保证每次出队列的执行时间是最早的,内部会自动扩容,最大扩容到Integer.MAX_VALUE,导致OOM。
线程池的大小设定
对于CPU密集型任务,一般设定为N+1,多出来一条用来保证某个线程因为其他原因而暂停,让这一条去占用CPU执行任务,充分利用CPU空闲时间。
对于I/O密集型任务,一般设定为2N,与I/O 交互,需要等待I/O的响应,可以让出CPU,切换线程。
标签:最大,队列,创建,阻塞,任务,线程,空闲 From: https://blog.csdn.net/weixin_45967584/article/details/137037077