第十七章 Java线程之ThreadGroup源码分析

前言

ThreadGroup,顾名思义,它是一组线程。但这是一个对象,所以可以理解为这是一个拥有一组线程的管理员。ThreadGroup这个管理员提供了一些管理方法,类似一栋楼的宿舍需要一个宿舍管理员。这样的好处是对某一些功能方便管理。比如,现在疫情发生了,每个人都是一个线程,防疫员如果挨个挨个的去测量体温,肯定吃不消,于是他通知宿管所:“你去负责这栋楼的体温测量”。所以,ThreadGroup就是这样一个统一管理的作用。

解析从变量入手

变量成员如下:
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是谁?
ThreadGroup的构造器告诉了我们:

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

如果我们要手动创建一个线程组,那么这个线程组肯定是当前线程组的子线程组:

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

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

它可以做什么

boolean parentOf(ThreadGroup g)  // 是不是它父亲
boolean isDaemon()   //是不是守护线程组 
int getMaxPriority()  // 最大优先级
synchronized boolean isDestroyed() // 线程组是否已消亡
int activeCount()  // 活着的线程还有多少
int activeGroupCount()  // 活着的子线程组有多少
批量中断、挂起等等
void interrupt()

除了中断本组的所有线程,还会中断所有子线程组中的线程

 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();
    }
}
消亡

结束本线程组,意味着其下所有的子线程组都会消亡。并从父线程组中删除本组。

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);
    }
}

总结

ThreadGroup提供了一些方法,用于批量管理线程。这在一定程度上带来了方便,但是使用不当可能会造成大范围异常。

猜你喜欢

转载自blog.csdn.net/weixin_43901067/article/details/106481643
今日推荐