线程组,顾名思义,就是线程的组,逻辑类似项目组,用于管理项目成员,线程组就是用来管理线程。
每个线程都会有一个线程组,如果没有设置将会有些默认的初始化设置
而在java中线程组则是使用类ThreadGroup 进行抽象描述
既然线程组是用来管理线程的,自然更多的是一种管理维度的抽象,所以很多方法也都是这个理念

构造方法

想要了解一个类的具体信息,第一个要看的就是构造方法,看一下最多的内容的那个构造方法就可以大致了解到有哪些属性了
ThreadGroup有两个构造方法
仔细看下这两个构造方法,其实只有一个了,那就是底层的私有的这一个
对于一个线程组来说,他拥有他自己的名字,也拥有他的优先级,也有是否是守护的说法
不同于线程,对于线程组来说,他是有记录自己的父线程组的,通过parent
另外,线程组也记录了自己下面有哪些线程组,使用数组记录,也就是构造方法中的  parent.add(this)
所以一个线程组核心的信息是:名称、优先级、是否守护、父线程组、子线程组
另外还有一个默认的构造方法,看注释,用来创建系统线程组
  

名称

线程组的名称借助于内部的name属性持有
通过构造方法可以设置名称
提供了get方法用于获取名称

优先级

此处的优先级,表示的是最大允许优先级,线程组内最大就允许这么大
里面所有的线程不能继续变大,不要认为是记录了里面所有的线程中最大的那个值,是一个天花板,不是一个记录尺

daemon

父线程组

对于线程组来说,是明确的记录了他的父
借助于parent这个属性值,可以获取一个线程组的父线程组,也可以用来确定是否是一个指定线程组的父或者祖先

子线程组

内部借助于ThreadGroup 数组维护内部的线程组,从这个数据组织结构来看,就很显然,线程组内可以有线程组,可以层层嵌套形成树状结构的
对于线程组的创建,他必然会有一个父线程组(不设置就是当前线程所在的线程组了,也可以简单说当前线程组)
创建线程组的时候,就会借助于add方法,将这个线程组加入到父线程组维护的数组内
对于任何一个线程,也都是拥有一个线程组,如果没有设置,将会将当前线程的线程组作为线程组,这个在前面已经说过
而在start方法中,又将当前线程添加到了线程组,请看下面的源码截图
在回头看下这个add方法,借助于内部的线程数组,其实就是将这个线程添加到数组内
  • nThreads 记录的就是线程组内部的线程个数
  • nUnstartedThreads记录的是未启动的个数
刚刚调用线程的start方法,这个数就要减1,尽管可能这个瞬间线程可能并没有真正的启动,确保能够明确的声明线程组内有启动的线程了
所以就由这几项数据组成了线程组的树形结构
也就是说
  • 每个线程组也都知道自己包含多少个线程,哪些线程;
  • 每个线程组也都知道自己包含了多少个线程组,哪些线程组;
这是一份很重要的信息,借助于这些信息就完全串联起来了

子线程组相关方法

既然是树形结构,那么自然可能有枚举节点的需求
ThreadGroup中提供了两类enumerate方法,看名字应该就可以理解含义了,用于枚举线程和线程组

线程枚举

底层依赖于私有枚举方法,把此线程组及其子组中的所有活动线程复制到指定数组中。可以设置是否递归枚举
两个方法中,如果不指定是否递归,那么默认是递归的,他们都将参数数组的第一个元素开始写入(0号下标)
很显然,他们内部就是借助于树结构的变量,nThreads和thread[]数组
需要注意的是,如果数组内空间不足,多余的线程将不能够保存进去,而且保存的是alive状态的
 

activeCount

该线程组以及子线程组中,活动线程的估计数。注意是一个估计数,估计数,估计数

activeGroupCount

类似activeCount,这个方法是返回的线程组的个数,仍旧是估计数,估计数,估计数

list方法

list看注释,用于调试,底层依赖方法list(PrintStream out, int indent),indent表示的是缩进,也就是空格个数
仍旧是借助于nthreads和ngroups以及threads数组和group数组,也就是树形结构循环遍历打印信息

interrupt()方法

中断此线程组中的所有线程,可以看得出来:
仍旧是遍历树形结构,核心是调用所有线程的interrupt方法
所以,此方法是中断该线程组以及所有子线程组中的所有线程

线程组的销毁

线程组的销毁内部借助于boolean变量 destroyed 进行标识
getter方法,isDestroyed直接返回此字段
而setter方法destroy,也是设置这个字段,但是还有一些逻辑判断与处理
destroy()负责销毁此线程组及其所有子组。
  • 会进行权限校验
  • 并且此线程组必须为空,也就是nthreads > 0不成立,也就是此线程组中的所有线程都已停止执行。
  • 并且会将子线程组中的也进行销毁,是递归进行的,显然,如果子线程组中线程非空,那么仍旧会抛出异常

权限校验checkAccess

checkAccess就是总提到的一个借助于安全管理器进行权限校验的封装
确定当前运行的线程是否有权修改此线程组

异常处理器

uncaughtException,是用于异常处理的设置,此处不讲,后续单独章节。

总结

从前面的描述可以看得出来,线程组就是对线程进行管理的一个抽象构建,他包括了自身的一些信息,还有一大部分就是对于线程的管理
线程组中有线程,也有线程组,借助于两个变量和两个数组完成了树形结构的构造,很多方法都是借助于这个树形结构完成的,比如枚举
想要理解线程组,就要理解线程组“管理”角色的内涵,并且对线程组的树形结构了解
既然是管理线程,所以线程中的一些功能或者属性也是依赖线程组的,比如优先级,线程不能超过线程组的最大优先级,再比如Thread中的activeCount(),实际上就是currentThread().getThreadGroup().activeCount();
总之,一定要理解管理二字的含义

线程组ThreadGroup分析详解 多线程中篇(三)的更多相关文章

  1. Java线程创建形式 Thread构造详解 多线程中篇(五)

    Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...

  2. InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)

      上一篇文章中对ThreadLocal进行了详尽的介绍,另外还有一个类: InheritableThreadLocal 他是ThreadLocal的子类,那么这个类又有什么作用呢?   测试代码 p ...

  3. Thread类详解 多线程中篇(二)

    Java.lang.Thread是Java应用程序员对Java多线程的第一站,Thread就是对Java线程本身的抽象 所以在Java中的线程编程概念中,一个Thread实例 == 一个线程 线程有哪 ...

  4. “全栈2019”Java多线程第十三章:线程组ThreadGroup详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  5. “全栈2019”Java多线程第二十二章:饥饿线程(Starvation)详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. “全栈2019”Java多线程第九章:判断线程是否存活isAlive()详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. “全栈2019”Java多线程第七章:等待线程死亡join()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  8. “全栈2019”Java多线程第五章:线程睡眠sleep()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. 线程池底层原理详解与源码分析(补充部分---ScheduledThreadPoolExecutor类分析)

    [1]前言 本篇幅是对 线程池底层原理详解与源码分析  的补充,默认你已经看完了上一篇对ThreadPoolExecutor类有了足够的了解. [2]ScheduledThreadPoolExecut ...

随机推荐

  1. Egret的按钮事件处理

    首先要在exml内要设置有对应按钮的ID 2,编写TypeScript脚本: public mybutton:eui.Button; 函数内部:this.mybutton.addEventListen ...

  2. 201771010126 王燕《面向对象程序设计(Java)》第十六周学习总结

    实验十六  线程技术 实验时间 2017-12-8 1.实验目的与要求 (1) 掌握线程概念: ‐多线程 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. ...

  3. 真正的ddos防御之道,简单干脆有效!

    话说,30G 就各种发博客 BB,唉,坦白说 ,博客园团队真心没见过世面 来 各位 先看图 啥意思呢? 就是哥的 最高防御是 600G.  没错,基本对当时的游戏没啥大的影响,10秒内恢复. 因为时间 ...

  4. 压力测试工具 ab

    ab 是Apache 自带的一个压力测试工具,命令行,是 ApacheBench 命令的缩写. ab的原理:ab命令会创建多个并发访问线程,模拟多个访问者同时对某一URL地址进行访问.它的测试目标是基 ...

  5. 使用ANY和ALL条件

    在比较运算符中,可以出现ALL和ANY,表示“全部”和“任一”,但是ALL和ANY不能单独使用,需要配合单行比较操作符>.>=.<.<=一起使用.其中: > ANY : ...

  6. FCC(ES6写法)Pairwise

    举个例子:有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算,只有7+13和9+11两种组合.而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11在数组的索引为2. ...

  7. 长沙学院APP之校园模块设计

    一.简单回顾 在上次的scrum冲刺中,我将整个长沙学院的APP做了一个基本的架构设计以及框架设计,确定好了APP的功能结构以及实现时所要达到的效果,并且做了一个简单的用户登录界面,由于所学知识有限, ...

  8. docker 及 docker-compose 的快速安装和简单使用

    本篇将使用 DaoCloud 源在 Ubuntu 上简单快速安装 docker 及 docker-compose 并添加了通过 Dockerfile 及 docker-compose.yml 使用 n ...

  9. 仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]

    本文为原创分享,转载请注明出处. 1.引言 即时通讯IM应用中的聊天消息时间显示是个再常见不过的需求,现在都讲究用户体验,所以时间显示再也不能像传统软件一样简单粗地暴显示成“年/月/日 时:分:秒”这 ...

  10. [Swift]LeetCode179. 最大数 | Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. Example ...