28.ThreadPoolExecutor

1.核心数据结构

ThreadPoolExecutor

//线程池状态和运行起来的线程数量
private final AtomicInteger ctl;
// 存放任务的阻塞队列
private final BlockingQueue<Runnable> workQueue;
// 对线程池内部各种变量进行互斥访问控制
private final ReentrantLock mainLock;
// 线程集合
private final HashSet<ThreadPoolExecutor.Worker> workers;

Worker

private final class Worker extends AbstractQueuedSynchronizer implements Runnable { 
    // ... 
    final Thread thread; // Worker封装的线程 
    Runnable firstTask;   // Worker接收到的第1个任务,可以是null,如果是null,则线程从队列获取任务
    volatile long completedTasks; // Worker执行完毕的任务个数 
    // ... 
}

2.核心配置参数

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, 
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
  1. corePoolSize:在线程池中始终维护的线程个数。
  2. maxPoolSize:在corePooSize已满、队列也满的情况下,扩充线程至此值。
  3. keepAliveTime/TimeUnit:maxPoolSize 中的空闲线程,销毁所需要的时间,总线程数收缩
    回corePoolSize。
  4. blockingQueue:线程池所用的队列类型。
  5. threadFactory:线程创建工厂,可以自定义,有默认值
    Executors.defaultThreadFactory() 。 6. RejectedExecutionHandler:corePoolSize已满,队列已满maxPoolSize 已满,最后的拒绝策略。

3.线程池关闭


这里的状态迁移有一个非常关键的特征:从小到大迁移,-1,0,1,2,3,只会从小的状态值往大的状态值迁移,不会逆向迁移。

正确关闭线程池的步骤
关闭线程池的过程为:在调用 shutdown()或者shutdownNow()之后,线程池并不会立即关闭,接下来需要调用 awaitTermination() 来等待线程池关闭。

shutdown()与shutdownNow()的区别
1.shutdown()不会清空任务队列,会等所有任务执行完成,shutdownNow()清空任务队列。
2.shutdown()只会中断空闲的线程,shutdownNow()会中断所有线程。

4 任务的提交过程分析

  • 如果当前线程数小于corePoolSize,则启动新线程。添加Worker,并将command设置为Worker线程的第一个任务开始执行。
  • 如果当前的线程数大于或等于corePoolSize,则调用workQueue.offer放入队列。如果线程池正在停止,则将任务从队列移除,并拒绝任务请求。否则,放入队列中后发现没有线程执行任务,开启新线程
  • 线程数大于maxPoolSize,并且队列已满,调用拒绝策略

5.任务的执行过程分析

Woker的run()方法的实现过程

  • 使用给定的第一个任务并利用线程工厂创建Worker实例,调用Woker的run方法,再调用ThreadPoolExecutor的runWorker方法执行线程的运行
  • runWorker:中断Worker封装的线程,此时任务线程就可以开始运行了。获取线程锁,执行task.run()方法,执行任务中的代码。w.completedTasks++,线程已完成的任务数加1

6.线程池的4种拒绝策略

workqueue用完之后在execute(Runnable command)的最后,调用了reject(command)执行拒绝策略

  • 调用者直接在自己的线程里执行,线程池不处理,比如到医院打点滴,医院没地方了,到你家自己操作吧
  • 线程池抛异常
  • 线程池直接丢掉任务,神不知鬼不觉
  • 删除队列中最早的任务,将当前任务入队列
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 7,976评论 0 4
  • 公元:2019年11月28日19时42分农历:二零一九年 十一月 初三日 戌时干支:己亥乙亥己巳甲戌当月节气:立冬...
    石放阅读 7,496评论 0 2
  • 今天上午陪老妈看病,下午健身房跑步,晚上想想今天还没有断舍离,马上做,衣架和旁边的的布衣架,一看乱乱,又想想自己是...
    影子3623253阅读 3,074评论 3 8

友情链接更多精彩内容