Chapter Seventeen Java Thread ThreadGroup Source Code Analysis

Preface

ThreadGroup, as the name suggests, it is a group of threads. But this is an object, so it can be understood as an administrator with a set of threads. The administrator of ThreadGroup provides some management methods, similar to the dormitory of a building, a dormitory administrator is required. The advantage of this is that it is convenient to manage certain functions. For example, now that an epidemic has occurred, everyone is a thread. If the epidemic prevention personnel measure body temperature one by one, they will definitely be overwhelmed, so he informs the dormitory office: "You are responsible for the temperature measurement of this building." Therefore, ThreadGroup is such a unified management role.

Analysis starts with variables

变量成员如下:
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[]; // 存储子线程组的数组集合

Through its variable structure, we can know that the entire thread group is composed of the following tree.
Insert picture description here
So who is the ThreadGroup of the root node?
The constructor of ThreadGroup tells us:

通过该构造器创建根节点:
private ThreadGroup() {     // called from C code
    this.name = "system";
    this.maxPriority = Thread.MAX_PRIORITY;
    this.parent = null;
}

If we want to manually create a thread group, then this thread group must be a child thread group of the current thread group:

public ThreadGroup(String name) {
    this(Thread.currentThread().getThreadGroup(), name);  // 将当前线程的所在组作为父线程组。
}

public ThreadGroup(ThreadGroup parent, String name) {
    this(checkParentAccess(parent), parent, name);
}

What it can do

check
boolean parentOf(ThreadGroup g)  // 是不是它父亲
boolean isDaemon()   //是不是守护线程组 
int getMaxPriority()  // 最大优先级
synchronized boolean isDestroyed() // 线程组是否已消亡
int activeCount()  // 活着的线程还有多少
int activeGroupCount()  // 活着的子线程组有多少
Batch interruption, suspension, etc.
void interrupt()

In addition to interrupting all threads in this group, it also interrupts threads in all child thread groups

 public final void interrupt() {
    int ngroupsSnapshot;
    ThreadGroup[] groupsSnapshot;
    synchronized (this) {
        checkAccess();
        for (int i = 0 ; i < nthreads ; i++) {
            threads[i].interrupt();
        }
        ngroupsSnapshot = ngroups;
        if (groups != null) {
            groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
        } else {
            groupsSnapshot = null;
        }
    }
    // 递归调用
    for (int i = 0 ; i < ngroupsSnapshot ; i++) {
        groupsSnapshot[i].interrupt();
    }
}
Die out

Ending this thread group means that all child thread groups under it will die. And delete this group from the parent thread group.

public final void destroy() {
    int ngroupsSnapshot;
    ThreadGroup[] groupsSnapshot;
    synchronized (this) {
        checkAccess();
        if (destroyed || (nthreads > 0)) {
            throw new IllegalThreadStateException();
        }
        ngroupsSnapshot = ngroups;
        if (groups != null) {
            groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
        } else {
            groupsSnapshot = null;
        }
        if (parent != null) {
            destroyed = true;
            ngroups = 0;
            groups = null;
            nthreads = 0;
            threads = null;
        }
    }
    // 递归调用
    for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
        groupsSnapshot[i].destroy();
    }
    if (parent != null) {
        parent.remove(this);
    }
}

to sum up

ThreadGroup provides some methods for batch management of threads. This brings convenience to a certain extent, but improper use may cause a wide range of abnormalities.

Guess you like

Origin blog.csdn.net/weixin_43901067/article/details/106481643