工作线程的工作实现 @Override public void run() { // 先执行传递过来的第一个任务 这里是一个小的优化 让线程直接执行第一个任务 不需要 // 放入任务队列再取出来执行了 firstTask.run(); thisThread = Thread.currentThread(); while (!isStopped) { try { // 是否使用时间就在这里显示出来了 Runnable task = useTimed ? taskQueue.poll(keepAliveTime, unit) : taskQueue.take(); if (task == null) { int i; boolean exit = true; // 如果当前线程数大于核心线程数 则使用 CAS 去退出 用于保证在线程安全下的退出 // 且保证线程的个数不小于 corePoolSize 下面这段代码需要仔细分析一下 if (ct.get() > corePoolSize) { do{ i = ct.get(); if (i <= corePoolSize) { exit = false; break; } }while (!ct.compareAndSet(i, i - 1)); if (exit) { return; } } }else { task.run(); } } catch (InterruptedException e) { // do nothing } } }我们现在来仔细分析一下,线程退出线程池的时候是如何保证线程池当中总的线程数是不小于 corePoolSize 的!首先整体的框架是使用 CAS 进行实现,具体代码为 do ... while 操作,然后在 while 操作里面使用 CAS 进行测试替换,如果没有成功再次获取,当线程池当中核心线程的数目小于等于 corePoolSize 的时候也需要退出循环,因为线程池当中线程的个数不能小于 corePoolSize。因此使用 break 跳出循环的线程是不会退出线程池的 。
线程池实现的BUG在我们自己实现的线程池当中当线程退出的时候,workers 当中还保存这指向这个线程的对象,但是当线程退出的时候我们还没有在 workers 当中删除这个对象,因此这个线程对象不会被垃圾回收器收集掉,但是我们这个只是一个线程池实现的例子而已,并不用于生产环境,只是为了帮助大家理解线程池的原理 。
经验总结扩展阅读
- [WPF] 抄抄超强的苹果官网滚动文字特效实现
- 交管12123电动车罚款怎么缴费流程一览
- 秦时明月配音演员表介绍?
- 谁敢动我灵鹫宫的人是第几集?
- 河南移动卡套餐 移动卡套餐一览表
- 防盗门门框松动应该怎么处理
- 暖手袋会自动断电吗 暖手袋有点漏水还能用吗
- 淘宝八月份有什么满减活动2023
- 寿命最长的爬行动物排行榜
- 世界上移动速度最快的蛇是什么蛇 世界上移动速度最快的蛇排行榜