Java线程组ThreadGroup详解

1 简介

线程组(ThreadGroup)是一个线程集合。是为了更方便地管理线程。线程组是父子结构的,一个线程组可以集成其他线程组,同时也可以拥有其他子线程组。从结构上看,线程组是一个树形结构,每个线程都隶属于一个线程组,线程组又有父线程组,这样追溯下去,可以追溯到一个根线程组——System线程组。

线程组树的结构

  • JVM创建的system线程组是用来处理JVM的系统任务的线程组,例如对象的销毁等
  • system线程组的直接子线程组是main线程组,这个线程组至少包含一个main线程,用于执行main方法
  • main线程组的子线程组就是应用程序创建的线程组。

你可以在main方法中看到JVM创建的system线程组和main线程组:

一个线程可以访问其所属线程组的信息,但不能访问其所属线程组的父线程组或者其他线程组的信息。

线程组的构造

java.lang.ThreadGroup 提供了两个构造函数:

Constructor Description
ThreadGroup(String name) 根据线程组名称创建线程组,其父线程组为main线程组
ThreadGroup(ThreadGroup parent, String name) 根据线程组名称创建线程组,其父线程组为指定的parent线程组
  • 两个构造函数的用法

ThreadGroup方法介绍

1.public ThreadGroup(ThreadGroup parent, String name)
分析:构建一个新的线程组,这个新组的父级是当前正在运行的线程的线程组;

2.public ThreadGroup(ThreadGroup parent, String name)
分析:构建一个新的线程组,这个新租的父级是指定的线程组;

3.public int activeCount()
分析:返回此线程组及其子组中活动线程的数量的估计值,递归遍历该线程组中所有的子组;
返回的值只是一个估计值,因为用这种方法遍历内部数据结构因为线程的数量可能会动态发生变化,并且可能会受到某些系统线程的影响,此方法主要用于调试和监视目的;

4.public int activeGroupCount()
分析:返回此线程组及其子组中活动组的数目的估计值。递归遍历该线程组中的所有子群。返回的值只是一个估计值,因为线程组的数量可能会动态变化,而这种方法遍历内部数据结构。此方法主要用于调试和监视目的。

5.public final void checkAccess()
分析:确定当前运行的线程是否具有修改此线程组的权限。
如果存在安全管理器,它的checkaccess方法调用这个线程组作为其参数。这可能会导致抛出SecurityException。

6.public final void destroy()
分析:破坏此线程组及其所有子组,此线程组必须为空,表示此线程组中的所有线程必须都停止;

7.public int enumerate(Thread[] list)
分析:将这个线程组复制到它所在的组及其子组中;

8.public int enumerate(Thread[] list, boolean recurse)
分析:将这个线程组复制到它所在的线程组,如果recurse是true,此方法递归枚举此线程组的所有子组,并对这些子组中的每个活动线程进行引用。如果数组太短无法保存所有的线程,额外的线程将被默默的忽略;

9.public int enumerate(ThreadGroup[] list)
分析:复制线程组中的活跃线程引用到它当前线程组及其子组中;

10.public int enumerate(ThreadGroup[] list, boolean recurse)
分析:复制线程组中的活跃线程引用到它当前线程组及其子组中,如果recurse是true,此方法递归枚举此线程组的所有子组,并对这些子组中的每个活动线程组进行引用。

11.public final int getMaxPriority()
分析:返回此线程组的最大优先级。作为该组的一部分的线程不能具有比优先级最高的优先级。

12.public final String getName()
分析:返回此线程组的名称;

13.public final ThreadGroup getParent()
分析:返回此线程组的父级;

14.public final void interrupt()
分析:终端此线程组中的所有线程;

15.public final boolean isDaemon()
分析:测试此线程组是否是守护线程组。当终止最后一个线程或它的最后一个线程组被销毁时,守护线程组会自动销毁;

16.public boolean isDestroyed()
分析:测试此线程组是否已被销毁;

17.public void list()
分析:将此线程组的信息打印到标准输出。此方法仅用于调试。

18.public final boolean parentOf(ThreadGroup g)
分析:测试此线程组是线程组参数还是其祖先线程组之一;

19.public final void setDaemon(boolean daemon)
分析:更改此线程组的守护进程状态;

20.public final void setMaxPriority(int pri)
分析:设置组的最大优先级。线程组中具有较高优先级的线程不会受到影响

查看当前线程组的信息。

public static void list(){
		ThreadGroup tg = new ThreadGroup ("subgroup 1");
		Thread t1 = new Thread (tg, "thread 1");
		Thread t2 = new Thread (tg, "thread 2");
		Thread t3 = new Thread (tg, "thread 3");
		tg = new ThreadGroup ("subgroup 2");
		Thread t4 = new Thread (tg, "my thread");
		tg = Thread.currentThread ().getThreadGroup ();
		int agc = tg.activeGroupCount ();
		System.out.println ("Active thread groups in " + tg.getName () + " thread group: " + agc);
		tg.list ();
}

输出如下:

Active thread groups in main thread group: 2
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=subgroup 1,maxpri=10]
    java.lang.ThreadGroup[name=subgroup 2,maxpri=10]

终止线程组中的所有线程

一个线程不应由其他线程来强制中断或停止,而是应该由线程自己自行停止。
因此 Thread.currentThread().stop(), Thread.currentThread().suspend(), Thread.currentThread().resume() 都已经被废弃了。
interrupt() 方法的作用是通知线程应该中断了,具体到底中断还是继续运行,由被通知的线程处理。

public class ThreadGroupExampleInterrupt {

    public static void main(String[] args) {

        // Start two threads
        MyThread mt = new MyThread();
        mt.setName("A");
        mt.start();
        mt = new MyThread();
        mt.setName("B");
        mt.start();

        // Wait 2 seconds
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Interrupt all methods in the same thread group as the main thread
        Thread.currentThread().getThreadGroup().interrupt();

    }


    //一个启动以后进入等待,直到被interrupt的线程
    static class MyThread extends Thread {
        public void run() {
            synchronized ("A") {
                System.out.println(getName() + " about to wait.");
                try {
                    "A".wait();
                } catch (InterruptedException e) {
                    System.out.println(getName() + " interrupted.");
                }
                System.out.println(getName() + " terminating.");
            }
        }
    }

}

复制代码执行main方法输出:

A about to wait.
B about to wait.
A interrupted.
A terminating.
B interrupted.
B terminating.
发布了337 篇原创文章 · 获赞 220 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/qq_33589510/article/details/104140643