前言
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提供了一些方法,用于批量管理线程。这在一定程度上带来了方便,但是使用不当可能会造成大范围异常。