Java并发编程实战 05 | 什么是线程组?

1.线程组介绍

在 Java 中,ThreadGroup 用于表示一组线程。通过 ThreadGroup,我们可以批量控制和管理多个线程,使得线程管理更加方便。

ThreadGroup 和 Thread 的关系就像它们的字面意思一样简单:每个线程 (Thread) 必定属于一个线程组 (ThreadGroup),线程不能脱离线程组而单独存在。

例如,方法 main() 中的线程名称是 main,如果在执行 new Thread() 时没有明确指定其 ThreadGroup,那么默认情况下,会将当前正在执行的线程(即父线程)的 ThreadGroup 设置为新线程的 ThreadGroup。

public class Demo {public static void main(String[] args) {Thread subThread = new Thread(() -> {System.out.println("The name of the thread group where subThread is located is:" +Thread.currentThread().getThreadGroup().getName());System.out.println("The name of the current thread (subThread) is:" +Thread.currentThread().getName());});subThread.start();System.out.println("The thread group name of the thread in which the main() method is executed is: "+ Thread.currentThread().getThreadGroup().getName());System.out.println("The name of the current thread is:"+ Thread.currentThread().getName());}
}//输出:
The thread group name of the thread in which the main() method is executed is: main
The name of the current thread is:main
The name of the thread group where subThread is located is:main
The name of the current thread (subThread) is:Thread-0

一个线程组可以包含多个线程,也可以包含多个子线程组。从结构上来看,线程组是一个树形结构,每个线程都属于一个线程组,线程组之间通过父子关系连接,最终追溯到一个根线程组,即系统线程组。

  1. JVM 创建的 系统线程组(system thread group)是用于处理 JVM 系统任务的一组线程,例如对象的销毁、垃圾回收(GC)等。
  2. 系统线程组的直接子线程组是 main 线程组,其中至少包含一个用于执行 main 方法的线程。
  3. 应用程序创建的所有线程组都是 main 线程组的子线程组。

我们可以查看 JVM 创建的 system 线程组以及 main 线程组。

public static void main(String[] args) {ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();ThreadGroup systemThreadGroup = mainThreadGroup.getParent();System.out.println("The name of the parent thread group of the thread group where the current thread is located = " + systemThreadGroup.getName());System.out.println("The name of the thread group where the current thread is located is = " + mainThreadGroup.getName());}//输出:
The name of the parent thread group of the thread group where the current thread is located = system
The name of the thread group where the current thread is located is = main

线程可以访问其所属的线程组的信息,但无法访问该线程组的父线程组或其他线程组的信息。

线程组构成

首先,让我们看看 ThreadGroup 源码中的成员变量。

public class ThreadGroup implements Thread.UncaughtExceptionHandler { 父线程组private final ThreadGroup parent; String name; int maxPriority;boolean destroyed;boolean daemon;boolean vmAllowSuspension;int nUnstartedThreads = 0;//子线程的数量int nthreads;   //子线程的数组Thread threads[]; //子线程组的数量int ngroups; //子线程组的数组ThreadGroup groups[];
}

接下来,我们来看一下 ThreadGroup 提供的两个构造函数。我会在代码中添加一些注释,以帮助大家更好地理解它们的功能和用法。

// JVM启动时调用,创建根线程组。
private ThreadGroup() { this .name = "system" ; this .maxPriority = Thread.MAX_PRIORITY; this .parent = null ; 
} 
//默认传入当前ThreadGroup作为父ThreadGroup,新线程组的父线程组就是当前运行线程的线程组。
public ThreadGroup(String name) { this (Thread.currentThread().getThreadGroup(), name); 
} 
//传入名称创建线程组,父线程由客户端指定。
public ThreadGroup(ThreadGroup parent, String name) { this (checkParentAccess(parent), parent, name); 
} 
//主私有构造函数,大部分参数继承自父线程组
private ThreadGroup(Void unused, ThreadGroup parent, String name) {this.name = name;this.maxPriority = parent.maxPriority;this.daemon = parent.daemon;this.vmAllowSuspension = parent.vmAllowSuspension;this.parent = parent;parent.add(this);
}

代码中的checkParentAccess() 方法用于验证当前线程是否具备对线程组进行修改的权限。这是为了确保线程组的安全性和一致性。

下面我将演示这两个构造函数的使用示例:

public class ConstructDemo {public static void main(String[] args) {ThreadGroup subThreadGroup1 = new ThreadGroup("subThreadGroup1");ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "subThreadGroup2");System.out.println("subThreadGroup1 parent name is: " + subThreadGroup1.getParent().getName());System.out.println("subThreadGroup2 parent name is: " + subThreadGroup2.getParent().getName());}
}//输出:
subThreadGroup1 parent name is: main
subThreadGroup2 parent name is: subThreadGroup1

ThreadGroup包含的方法介绍

ThreadGroup 提供了许多有用的方法,下面简要介绍一下。

我们选择了一些方法通过代码来演示其用法。

public class ThreadGroupMethodCase {public static void main(String[] args) throws InterruptedException {ThreadGroup subgroup1 = new ThreadGroup("subgroup1");Thread t1 = new Thread(subgroup1, "t1 in subgroup1");Thread t2 = new Thread(subgroup1, "t2 in subgroup1");Thread t3 = new Thread(subgroup1, "t3 in subgroup1");t1.start();Thread.sleep(50);t2.start();int activeThreadCount = subgroup1.activeCount();System.out.println("Active thread in " + subgroup1.getName() + " thread group: " + activeThreadCount);ThreadGroup subgroup2 = new ThreadGroup("subgroup2");Thread t4 = new Thread(subgroup2, "t4 in subgroup2");ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();int activeGroupCount = currentThreadGroup.activeGroupCount();System.out.println("Active thread groups in " + currentThreadGroup.getName() + " thread group: " + activeGroupCount);System.out.println("Prints information about currentThreadGroup to the standard output:");currentThreadGroup.list();}
}//输出:
Active thread in subgroup1 thread group: 2
Active thread groups in main thread group: 2
Prints information about currentThreadGroup to the standard output:
java.lang.ThreadGroup[name=main,maxpri=10]Thread[main,5,main]java.lang.ThreadGroup[name=subgroup1,maxpri=10]java.lang.ThreadGroup[name=subgroup2,maxpri=10]

这里要注意的一点是,在输出当前线程组中的活动线程数时,只计算状态为 RUNNABLE、BLOCKED、WAITING 或 TIMED_WAITING 的线程,不包括状态为 NEW 或 TERMINATED 的线程。

因此,当我们调用 subgroup1.activeCount() 时,它实际上只会返回当前活动的线程数。举例来说,如果线程 t1 已经结束,而线程 t3 尚未启动,那么只有线程 t2 被计算在内。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1527650.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于R语言的统计分析基础:操作XML文件与YAML文件

XML文件简介 在处理从文本文件中读取数据的任务时,用户承担着至关重要的责任,即需要充分理解和明确指定在创建该文件时所遵循的一系列约定和规范。这些约定涵盖了多个方面,包括但不限于: 注释字符:识别并忽略文件中用…

kubeadm 初始化 k8s 证书过期解决方案

概述 在使用 kubeadm 初始化的 Kubernetes 集群中,默认情况下证书的有效期为一年。当证书过期时,集群中的某些组件可能会停止工作,导致集群不可用。本文将详细介绍如何解决 kubeadm 初始化的 Kubernetes 集群证书过期的问题,并提…

CSP-J基础之常见的竞赛题库

文章目录 CSP-J基础之常见的竞赛题库1. 可达 (KEDA)2. 洛谷 (Luogu)3. Codeforces 洛谷账号的注册总结 CSP-J基础之常见的竞赛题库 在备战CSP-J(Certified Software Professional Junior)及其他信息学竞赛时,选手们常需要借助在线题库来进行…

android framework工程师遇到成长瓶颈迷茫怎么办?千里马经验分享

背景 近来有一些framework老司机粉丝朋友发来了一些framework工作中的一些疑问,具体描述如下: 这个同学遇到的问题,其实就是大部分framework开发者工作比较久后遇到的一个上升瓶颈问题。 具体总结有以下几个瓶颈问题 1、framework属于系…

Clion不识别C代码或者无法跳转C语言项目怎么办?

如果是中文会显示: 此时只需要右击项目,或者你的源代码目录,将这个项目或者源码目录标记为项目源和头文件即可。 英文如下:

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介 1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置&a…

【MacOS】mac定位服务中删除已经卸载的软件

mac定位服务中删除已经卸载的软件 网上的帖子真不靠谱 直接右键 WeTypeSettings ,查找位置,丢废纸篓即可!会提示你卸载的!

VLAN原理学习笔记

以太网是一种基于CSMA/CD的数据网络通信技术,其特征是共享通信介质。当主机数目较多时会导致安全隐患、广播泛滥、性能显著下降甚至造成网络不可用。 在这种情况下出现了VLAN (Virtual Local Area Network)技术解决以上问题。 1、VLAN快速配置 Vlan:Virtual Local…

C和指针:结构体(struct)和联合(union)

结构体和联合 结构体 结构体包含一些数据成员,每个成员可能具有不同的类型。 数组的元素长度相同,可以通过下标访问(转换为指针)。但是结构体的成员可能长度不同,所以不能用下标来访问它们。成员有自己的名字,可以通过名字访问…

springboot流浪天使乐园管理系统

基于springbootvue实现的流浪天使乐园管理系统(源码L文ppt)4-039 第4章 系统设计 4.1 总体功能设计 一般个人用户和管理者都需要登录才能进入流浪天使乐园管理系统,使用者登录时会在后台判断使用的权限类型,包括一般使用者…

以太网交换机工作原理学习笔记

在网络中传输数据时需要遵循一些标准,以太网协议定义了数据帧在以太网上的传输标准,了解以太网协议是充分理解数据链路层通信的基础。以太网交换机是实现数据链路层通信的主要设备,了解以太网交换机的工作原理也是十分必要的。 1、以太网协议…

Qt/C++编写的Onvif调试助手调试神器工具/支持云台控制/预置位设置等/有手机版本

一、功能特点 广播搜索设备,支持IPC和NVR,依次返回。可选择不同的网卡IP进行对应网段设备的搜索。依次获取Onvif地址、Media地址、Profile文件、Rtsp地址。可对指定的Profile获取视频流Rtsp地址,比如主码流地址、子码流地址。可对每个设备设…

ESP32_获取心知天气

目录 前言 一、获取心知天气API 二、编写代码 1.下载代码 2.代码讲解 1.安装Arduino.Json库 2.输入WIFI名称和密码 3.添加API 4.关于API的补充 三.数据的打印和处理 1.获取的数据 2.数据输出 总结 前言 环境:Arduino 芯片:ESP32 软件&…

基于springboot+vue实现的农家乐管理系统

基于springbootvue实现的山庄农家乐管理系统前后端分离项目(文末查看源码lw)4-10 系统角色: 管理员、用户 主要功能: (1)用户关键功能包含用户注册登陆、个人信息修改、首页、农家乐、美食信息、民宿信息…

【LeetCode】20.有效的括号

题目要求 解题思路 利用栈来解决本道题&#xff0c;左括号进栈&#xff0c;右括号出栈。需要判断第一个字符是右括号的情况 代码实现 class Solution { public:bool isValid(string s) {//利用栈来解决stack<char> st;for(auto& e:s){//是左括号就进if(e(||e[||…

SpringBoot开启多端口探究--基于多ApplicationContext

文章目录 前情提要一、思路概要二、具体实现三、其他问题父子关系部分依赖 总结 前情提要 前面探讨了management端口开启&#xff0c;grpc端口开启&#xff0c;本文继续探讨在SpringApplication中开启多个端口的方式之多ApplicationContext, 相比management端口基于多WebServe…

java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式在最下方 java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频) 停车管理信息系统是为了提升停车场的运营效率和管理水平而设计的综合性平台。系统涵盖用户信息管理、车位管理、收费管理、违规车辆处理等多个功能…

基于Spring Boot的火车订票管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JAVA语言 Spring Boot框架 工具&#xff1a;IDEA/Eclipse、Navicat、Tomcat 系统展示 首页 管理…

【动手学深度学习】05 线性代数(个人向笔记)

1. 线性代数 向量的一些公式 ∣ ∣ a ∣ ∣ ||a|| ∣∣a∣∣ 表示向量 a 的范数&#xff0c;课上没有讲范数的概念 其中第一条为求向量的二范数 第四条表示如果a为标量&#xff0c;那么向量 ∣ ∣ a ⋅ b ∣ ∣ ||ab|| ∣∣a⋅b∣∣ 的长度等于 ∣ a ∣ ⋅ ∣ ∣ b ∣ ∣…

Ifream实现微前端效果

记得有人曾问过我&#xff0c;老旧的项目内容很多&#xff0c;项目卡&#xff0c;想要改造成类似微前端&#xff0c;领导想要快速&#xff0c;又不想系统重构、而且是不同子系统的协同&#xff0c;要怎么做&#xff1f;对方不想做太大的改造&#xff0c;所以想用ifream的方式动…