Java并发之线程组ThreadGroup介绍

线程组介绍

线程组(ThreadGroup)简单来讲就是一个线程集合。线程组的出现是为了更方便地管理线程。github

线程组是父子结构的,一个线程组能够集成其余线程组,同时也能够拥有其余子线程组。从结构上看,线程组是一个树形结构,每一个线程都隶属于一个线程组,线程组又有父线程组,这样追溯下去,能够追溯到一个根线程组——System线程组。编程

<div align=center>多线程


</div>并发

下面介绍一下线程组树的结构:函数

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

你能够在main方法中看到JVM建立的system线程组和main线程组:post

public static void main(String[] args) {
      ThreadGroup mainThreadGroup=Thread.currentThread().getThreadGroup();
      ThreadGroup systenThreadGroup=mainThreadGroup.getParent();
      System.out.println("systenThreadGroup name = "+systenThreadGroup.getName());
      System.out.println("mainThreadGroup name = "+mainThreadGroup.getName());
  }

console输出:this

systenThreadGroup name = system
mainThreadGroup name = main

一个线程能够访问其所属线程组的信息,但不能访问其所属线程组的父线程组或者其余线程组的信息。spa

线程组的构造

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

Constructor Description
ThreadGroup(String name) 根据线程组名称建立线程组,其父线程组为main线程组
ThreadGroup(ThreadGroup parent, String name) 根据线程组名称建立线程组,其父线程组为指定的parent线程组

下面演示一下这两个构造函数的用法:

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

console输出:

subThreadGroup1 parent name = main
subThreadGroup2 parent name = subThreadGroup1

ThreadGroup方法介绍

ThreadGroup提供了不少有用的方法,下面提供了这些方法的简要介绍,以及部分方法的使用示例。

S.N. Method Description
1) void checkAccess() This method determines if the currently running thread has permission to modify the thread group.
2) int activeCount() This method returns an estimate of the number of active threads in the thread group and its subgroups.
3) int activeGroupCount() This method returns an estimate of the number of active groups in the thread group and its subgroups.
4) void destroy() This method destroys the thread group and all of its subgroups.
5) int enumerate(Thread[] list) This method copies into the specified array every active thread in the thread group and its subgroups.
6) int getMaxPriority() This method returns the maximum priority of the thread group.
7) String getName() This method returns the name of the thread group.
8) ThreadGroup getParent() This method returns the parent of the thread group.
9) void interrupt() This method interrupts all threads in the thread group.
10) boolean isDaemon() This method tests if the thread group is a daemon thread group.
11) void setDaemon(boolean daemon) This method changes the daemon status of the thread group.
12) boolean isDestroyed() This method tests if this thread group has been destroyed.
13) void list() This method prints information about the thread group to the standard output.
14) boolean parentOf(ThreadGroup g) This method tests if the thread group is either the thread group argument or one of its ancestor thread groups.
15) void suspend() This method is used to suspend all threads in the thread group.
16) void resume() This method is used to resume all threads in the thread group which was suspended using suspend() method.
17) void setMaxPriority(int pri) This method sets the maximum priority of the group.
18) void stop() This method is used to stop all threads in the thread group.
19) String toString() This method returns a string representation of the Thread group.

查看线程组信息

下面演示了查看当前线程组的信息。

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.

总结

本节介绍了线程组ThreadGroup的概念,及其结构和构造函数,并演示了使用线程组方便地管理组内线程的几个方法。

本节是并发系列教程的一节,更多相关教程能够访问文章后面的连接。

后续会有更多关于并发编程的知识点的介绍,而且会结合企业项目进行实战介绍,欢迎继续关注。

Links

做者资源

做者:涛哥 ( ijiangtao.net ) 公众号:西召 ( westcall ) 欢迎 评论、关注、打赏,转发和点赞,你的鼓励是我持续创做的动力。 涛哥这里,干货和湿货,包罗万象!
相关文章
相关标签/搜索