当前位置: 首页> 汽车> 维修 > Java并发编程实战 05 | 什么是线程组?

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

时间:2025/8/23 8:22:51来源:https://blog.csdn.net/weixin_42627385/article/details/141983202 浏览次数: 0次

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 被计算在内。

关键字:Java并发编程实战 05 | 什么是线程组?

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: