文章目录

  • 一、keepAliveTime的概念
  • 二、keepAliveTime的设置方法
    • 2.1. 通过构造函数设置
    • 2.2. 通过setKeepAliveTime方法动态设置
  • 三、线程是如何根据keepAliveTime进行销毁的

阅读这篇文章,你将会知道:
keepAliveTime的概念。
keepAliveTime是如何设置的。
线程是如何根据keepAliveTime进行销毁的。

一、keepAliveTime的概念
  • 1 keepAliveTime的单位是纳秒,即1s=1000000000ns,1秒等于10亿纳秒。
  • 2 keepAliveTime是线程池中空闲线程等待工作的超时时间。
  • 3 当线程池中线程数量大于corePoolSize(核心线程数量)或设置了allowCoreThreadTimeOut(是否允许空闲核心线程超时)时,线程会根据- 1 keepAliveTime的值进行活性检查,一旦超时便销毁线程。
  • 4 否则,线程会永远等待新的工作。
    /*** Timeout in nanoseconds for idle threads waiting for work.* Threads use this timeout when there are more than corePoolSize* present or if allowCoreThreadTimeOut. Otherwise they wait* forever for new work.*/private volatile long keepAliveTime;
二、keepAliveTime的设置方法
2.1. 通过构造函数设置

通过 keepAliveTime 、unit共同决定实际的 keepAliveTime值,最终会转化成纳秒单位。

2.2. 通过setKeepAliveTime方法动态设置

重新设置线程池的keepAliveTime属性,如果发现将要设置的值比原来的keepAliveTime值要小(即减小keepAliveTime),则触发interruptIdleWorkers(),中断空闲线程。

interruptIdleWorkers()是怎么中断线程的呢?
(1)interruptIdleWorkers先拿出所有的工作者进行遍历,判断工作者对应的线程是否已经中断。
(2)如果没有产生中断,则判断是否可以获得锁,如果能获得锁,则代表是空闲线程,然后中断该线程。
(3)至于线程的中断在什么时候会抛出中断异常,同学们可以自己找下资料,也可以参考下别人写的这篇文章Java并发之线程中断

三、线程是如何根据keepAliveTime进行销毁的
  • 1.线程池中的线程通过工作者(Worker)这个类进行包装,Worker通过 ThreadPoolExecutor.runWorker() 这个方法进行自旋,从队列中获得task,并完成工作。

  • 2.如果拿不到task(即firstTask == null 或 getTask() == null),则会退出自旋,进入finally代码块。finally中会调用processWorkerExit方法,注销当前Worker,实现worker的销毁。对keepAliveTime的使用,就在getTask()方法中,这个在后面讲解。

  • 3.getTask 怎么使用 keepAliveTime
    (1)首先也是一个自旋,当allowCoreThreadTimeout(运行空闲核心线程超时) 或 wc>corePoolSize(当前线程数量大于核心线程数量) 时,timed会标识为true,表示需要进行超时判断。
    (2)当wc(当前工作者数量)大于 最大线程数 或 空闲线程的空闲时间大于keepAliveTime(timed && timeout),以及wc>1或(workQueue)任务队列为空时,会进入compareAndDecrementWorkerCount方法,对wc的值减1。
    (3)当compareAndDecrementWorkerCount方法返回true时,则getTask方法会返回null,终止getTask方法的自旋。这时候回到runWorker方法,就会进入到processWorkerExit方法,进行销毁worker。

  • 4.compareAndDecrementWorkerCount中操作的是ctl属性:
    (1)ctl是中心控制器,一个AtomicInteger类型的整数,通过数字的二进制编码的位进行分段,不同的二进制位段表示有不同的含义。
    (2)在ctl中,低29为表示线程池的容量,即线程池最大容量为 536870911 = 000 11111111111111111111111111111。

 /*** The main pool control state, ctl, is an atomic integer packing* two conceptual fields*   workerCount, indicating the effective number of threads*   runState,    indicating whether running, shutting down etc*/private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));// COUNT_BITS = 29private static final int COUNT_BITS = Integer.SIZE - 3;// CAPACITY = 536870911 = 000 11111111111111111111111111111private static final int CAPACITY   = (1 << COUNT_BITS) - 1;private static int workerCountOf(int c)  { return c & CAPACITY; }

ThreadPoolExecutor中的keepAliveTime详解相关推荐

  1. ALSA声卡驱动中的DAPM详解之四:在驱动程序中初始化并注册widget和route

    前几篇文章我们从dapm的数据结构入手,了解了代表音频控件的widget,代表连接路径的route以及用于连接两个widget的path.之前都是一些概念的讲解以及对数据结构中各个字段的说明,从本章开 ...

  2. Asp.net中GridView使用详解(引)【转】

    Asp.net中GridView使用详解(引) GridView无代码分页排序 GridView选中,编辑,取消,删除 GridView正反双向排序 GridView和下拉菜单DropDownList ...

  3. Linux中iptraf命令详解(IP局域网监控工具)

    2019独角兽企业重金招聘Python工程师标准>>> Linux中iptraf命令详解(IP局域网监控工具) 发布时间:2017-12-27 20:46:03   作者:佚名    ...

  4. ArcGIS Engine中的Symbols详解

    转自原文 ArcGIS Engine中的Symbols详解 本文由本人翻译ESRI官方帮助文档.尊重劳动成果,转载请注明来源. Symbols ArcObjects用了三种类型的Symbol(符号样式 ...

  5. js路由在php上面使用,React中路由使用详解

    这次给大家带来React中路由使用详解,React中路由使用的注意事项有哪些,下面就是实战案例,一起来看一下. 路由 通过 URL 映射到对应的功能实现,React 的路由使用要先引入 react-r ...

  6. Linux中etc目录详解

    Linux中etc目录详解 /etc目录 包含很多文件.许多网络配置文件也在/etc 中. /etc/rc   or/etc/rc.d   or/etc/rc*.d   启动.或改变运行级时运行的sc ...

  7. java 自定义正则表达式_java中正则表达式实例详解

    Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * ...

  8. numpy中reshape方法详解

    numpy中reshape方法详解_zhanggonglalala的博客-CSDN博客_reshape

  9. JavaScript中getBoundingClientRect()方法详解

    JavaScript中getBoundingClientRect()方法详解 getBoundingClientRect() 这个方法返回一个矩形对象,包含四个属性:left.top.right和bo ...

最新文章

  1. LeetCode Remove Duplicates from Sorted List II
  2. redis3.2.3安装部署实战
  3. 如何跟随有三从零进阶中级CV算法工程师
  4. python中dict的fromkeys用法教程
  5. 免费2款标注工具实操(内含下载链接)
  6. Android 用java代码动态修改UI界面
  7. You Probably Dont Need Derived State
  8. atitit.404错误的排查流程总结vOa6
  9. 【亲测有效】解决电脑不能复制粘贴的几种方法
  10. oceancolor数据批量下载
  11. 互联网变迁-真实化信息的转移
  12. Django的模板语言DTL介绍以及渲染方式
  13. ModuleNotFoundError: No module named ‘myitem.myapp‘
  14. TIA博途中如何使用符号方式按位,字节,字访问非结构数据类型
  15. 周报 | 吉吉拍数字商品交易平台
  16. 2021年四川省大学生信息安全技术大赛部分WP (四川省赛WP)
  17. Linux雷鸟邮件,thunderbird雷鸟mail
  18. DAU ARPU 美术
  19. 韶关学院计算机科学学院简介
  20. 如何在win11上浏览政府IE网站

热门文章

  1. “骗子”成民企院士第一人:把认真当信仰,人生就会开挂
  2. 任正非:感谢美国,帮我把华为给全世界都宣传了
  3. 赌场圣手(从不失手)——隐马尔可夫!
  4. linux双屏播放视频,Ubuntu Linux下双屏显示解决方案
  5. 获取网站服务器数据库,利用XmlHttp获取服务器数据库数据以表格的方式返回客户的代码示例...
  6. java邮箱exchange_使用Javamail访问Microsoft Exchange邮箱(IMAP,MS Exchange)
  7. Python 的协程
  8. 优先队列c++ STL用法
  9. Windows 中_T和L
  10. 海云健康:上云为10万家药店带去了什么价值?