线程池
2021-05-19 11:23:40 35 举报
AI智能生成
对于线程池的一些知识整理
作者其他创作
大纲/内容
解决场景
频繁申请/销毁资源和调度资源,将带来额外的消耗,可能会非常巨大。
对资源无限申请缺少抑制手段,易引发系统资源耗尽的风险。
系统无法合理管理内部的资源分布,会降低系统的稳定性。
线程的状态
RUNNING
能接受新提交的任务,并且也能处理阻塞队列中的任务
SHUTDOWN
关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务
STOP
不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程
TIDYYING
所有的任务都已终止,workerCount(有效线程数)为0
TERMINATED
在terminated()方法执行完后进入该状态
任务执行机制
任务调度流程
1. 首先检测线程池运行状态,如果不是RUNNING,则直接拒绝,线程池要保证在RUNNING的状态下执行任务。
2. 如果workerCount < corePoolSize,则创建并启动一个线程来执行新提交的任务。
3. 如果workerCount >= corePoolSize,且线程池内的阻塞队列未满,则将任务添加到该阻塞队列中。
4. 如果workerCount >= corePoolSize && workerCount < maximumPoolSize,且线程池内的阻塞队列已满,则创建并启动一个线程来执行新提交的任务。
5. 如果workerCount >= maximumPoolSize,并且线程池内的阻塞队列已满, 则根据拒绝策略来处理该任务, 默认的处理方式是直接抛异常。
任务缓冲[等待队列]
ArrayBlockingQueue
一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁
LinkedBlockingQueue
一个由链表结构组成的有界队列,次队列按照先进先出的原则对元素进行排序。此队列的长度默认为Integer.MAX_VALUE,所以默认创建的该队列有容量危险
PriorityBlockingQueue
一个支持线程优先级排序的无界队列,默认自然顺序排序,也可以自定义是先 compareTo()方法来执行元素排序规则,不能保证同优先级的顺序
DelayQueue
一个实现PriorityBlockingQueue实现延迟获取的无界队列,在创建元素时,可以指定多久才能从队列中获取当前元素。只有延时期满后才能从队列中获取元素。
SynchronousQueue
一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。支持公平锁和非公平锁。
SynchronousQueue的一个使用场景是在线程池里:Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。
SynchronousQueue的一个使用场景是在线程池里:Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。
LinkedTransferQueue
一个由链表结构组成的无界阻塞队列,相当于其他队列,LinkedTransferQueue队列多了transfer和tryTransfer方法
LinkedBlockingDeque
一个由链表结构组成的双向阻塞队列,队列头部和尾部都可以添加和移动元素,多线程并发时,可以将锁的竞争最多降到一半。
任务拒绝
ThreadPoolExecutor.AbortPolicy
丢弃任务并抛出RejectedExecutionException异常。这是线程池默认的拒绝策略,在任务不能再提交的时候抛出异常,及时反馈程序运行状态。关键业务不建议是用;
ThreadPoolExecutor.DiscardPolicy
丢弃任务,但是不抛出异常;使用该策略可能会使我们无法发现系统的异常状态。建议非关键业务使用
ThreadPoolExecutor.DiscardOldestPolicy
丢弃队列最前面的任务,然后重新提交被拒绝的任务。
ThreadPoolExecutor.CallRunsPolicy
由调用线程(提交任务的线程)处理该任务。适合大量计算的任务类型去执行,多线程仅仅是增大吞吐量,最终必须要让每个任务都必须执行完毕;
功能
降低资源消耗
通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗
提高响应速度
任务到达时,无需等待线程池创建即可立即执行
提高线程的管理性
线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调度和监控
提供更多更强大的功能
线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。
常用场景
内存池(Memory Pooling)
预先申请内存,提升申请内存速度,减少内存碎片。
连接池(Connection Pooling)
预先申请数据库连接,提升申请连接的速度,降低系统的开销。
实例池(Object Pooling)
循环使用对象,减少资源在初始化和释放时的昂贵损耗。
worker线程管理
worker线程
作用
每个任务通过线程池添加进来的都会被分装成Worker,Worker实现Runnable接口,持有一个Thread,用来监控当前的任务状态
生命周期
管理着任务的创建、执行、销毁、中断、回收等功能
集成AQS来实现独占锁并通过不可重入的方式去反应线程当前的执行状态
1. lock方法一旦获取独占锁,表示当前任务正在执行中
2. 如果正在执行任务,则不应该中断线程
3. 如果该线程现在不是独占锁的状态,也就是空闲状态,说明它没有处理任务,这时可以对该线程进行中断
4. 线程池正在进行shutdown方法或tryTerminate方法时会调用interruptIdleWorkers来中断空闲线程,
interruptIdleWorkers方法会使用tryLock方法来判断线程池中的状态是否空闲状态;如果空闲则可以安全回收;
interruptIdleWorkers方法会使用tryLock方法来判断线程池中的状态是否空闲状态;如果空闲则可以安全回收;
增加worker线程
0 条评论
下一页