线程池有哪几种 线程池

线程池工作原理管理线程,当线程执行完当前任务,不会死掉而是 会从队列里面取
1.降低系统资源消耗 。通过复用已存在的线程,降低线程创建和销毁造成的消耗;
2.提高响应速度 。当有任务到达时,无需等待新线程的创建便能立即执行;
3.提高线程的可管理性 。线程是稀缺资源,如果无限制的创建,不仅会消耗大量系统资源,还会降低系统的稳定性,使用线程池可以进行对线程进行统一的分配、调优和监控 。
本文主要是围绕 ThreadPoolExecutor(线程池框架的核心类)的构造方法参数 展开:
1.corePoolSize
线程池中的核心线程数 。当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行 。
2.maximumPoolSize
【线程池有哪几种 线程池】 额外最大线程数 。上面说到任务数足够多,且使用的是有界队列,如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,首先从队列里面取,如果队列里面的消息执行完毕,等下一定时间,额外线程自动销毁 。
3.keepAliveTime
线程空闲时的存活时间 。默认情况下,可以理解成额外最大线程数没活干了,额外线程线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize 。但是如果调用了allowCoreThreadTimeOut(boolean)方法,keepAliveTime参数也会起作用,直到线程池中的线程数为0 。
4.unit
keepAliveTime参数的时间单位 。
5.workQueue
任务缓存队列,用来存放等待执行的任务 。如果当前线程数为corePoolSize,继续提交的任务就会被保存到任务缓存队列中,等待被执行 。
一般来说,这里的BlockingQueue有以下三种选择:
* SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态 。因此,如果线程池中始终没有空闲线程(任务提交的平均速度快于被处理的速度),可能出现无限制的线程增长 。
* LinkedBlockingQueue:基于链表结构的阻塞队列,如果不设置初始化容量,其容量为Integer.MAX_VALUE,即为无界队列 。因此,如果线程池中线程数达到了corePoolSize,且始终没有空闲线程(任务提交的平均速度快于被处理的速度),任务缓存队列可能出现无限制的增长 。
* ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务 。
6.threadFactory
线程工厂,创建新线程时使用的线程工厂 。
7.handler
任务拒绝策略,当阻塞队列满了,且线程池中的线程数达到maximumPoolSize,如果继续提交任务,就会采取任务拒绝策略处理该任务,线程池提供了4种任务拒绝策略:
*AbortPolicy :丢弃任务并抛出RejectedExecutionException异常,默认策略;
*CallerRunsPolicy :由调用execute方法的线程执行该任务;
*DiscardPolicy :丢弃任务,但是不抛出异常;
*DiscardOldestPolicy :丢弃阻塞队列最前面的任务,然后重新尝试执行任务(重复此过程) 。
* 当然也可以根据应用场景实现 RejectedExecutionHandler 接口,自定义饱和策略,如记录日志或持久化存储不能处理的任务 。
总结下上诉参数:假设corePoolSize为10 ,maximumPoolSize为10,线程空闲时的存活时间为60s,队列采用的是有界队列ArrayBlockingQueue 设置阈值200,使 用拒绝策略,当前2000个任务提交过来 流程如下图
参数案例描述:
当前2000笔 任务进来,10个核心线程去处理,剩下的1990任务队列里面放200个 。剩下的1790个任务 。队列塞满会去创建10个额外线程和核心线程一起去 去执行剩下的1780个任务 。当还有剩下任务处理不了就会触发任务拒绝策略。
当前220笔 任务进来,10个核心线程去处理,剩下的210任务队列里面放200个 。剩下的10个任务 。队列塞满会去创建10个额外线程 去执行队列放不下的任务 。当额外线程和核心线程处理完队列里面的队列 。没有任务可执行时,额外线程会等待我们设置的keepAliveTime,还是没有任务的情况下,就会被回收了。
以上是绝对理想的状况下 。
由参数可知 核心线程 和额外线程值是相同的,额外线程被回收时间是0,采用的是无界队列 。默认采用的拒绝策略为 AbortPolicy 。分析得 核心线程和额外线程处理不过来得情况,会一直往队列里面放任务 。
可能存在的问题:队列过大 导致内存溢出 OOM
当任务量足够大,超过队列 。交由额外线程处理 。就会创建过多线程。

秒懂生活扩展阅读