首页 > 编程语言 >Java并发编程实战 05 | 什么是线程组?

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

时间:2024-09-07 09:52:03浏览次数:3  
标签:Java name thread 05 ThreadGroup Thread 线程 main

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,name,thread,05,ThreadGroup,Thread,线程,main
From: https://blog.csdn.net/weixin_42627385/article/details/141983202

相关文章