线程组代表一组线程。 此外,线程组还可以包括其他线程组。 线程组形成一个树,除了初始线程组之外,每个线程组都有一个父进程。
允许线程访问有关其线程组的信息,但不能访问有关其线程组的父线程组或任何其他线程组的信息。
package java.lang;
import java.io.PrintStream;
import java.util.Arrays;
import sun.misc.VM;
public class ThreadGroup implements Thread.UncaughtExceptionHandler {
// 父线程组
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[];
// 构造函数
private ThreadGroup() {
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);
}
// 构造函数,
private ThreadGroup(Void unused, ThreadGroup parent, String name) {
this.name = name;
this.maxPriority = parent.maxPriority;
this.daemon = parent.daemon;
this.vmAllowSuspension = parent.vmAllowSuspension;
// 设置父线程组
this.parent = parent;
parent.add(this);
}
// 校验父类的可达性
private static Void checkParentAccess(ThreadGroup parent) {
// 可达性分析
parent.checkAccess();
return null;
}
// 获取当前线程组的名字
public final String getName() {
return name;
}
//获取当前线程组的父线程组
public final ThreadGroup getParent() {
if (parent != null)
parent.checkAccess();
return parent;
}
// 获取优先级
public final int getMaxPriority() {
return maxPriority;
}
// 此线程是不是守护线程
public final boolean isDaemon() {
return daemon;
}
// 该线程组是不已经销毁
public synchronized boolean isDestroyed() {
return destroyed;
}
// 更改此线程组的守护程序状态。
public final void setDaemon(boolean daemon) {
// 校验可达性
checkAccess();
this.daemon = daemon;
}
// 设置最大的优先级
public final void setMaxPriority(int pri) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
// 同步代码块
synchronized (this) {
// 校验可达性
checkAccess();
// 比最小的小,比最大的大,则不设置
if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
return;
}
// 子类的优先级不能比父类的优先级大,
maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri;
ngroupsSnapshot = ngroups;
//
if (groups != null) {
// 将groups复制到ngroupsSnapshot
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
// 为其子线程组都设置上最大的优先级
groupsSnapshot[i].setMaxPriority(pri);
}
}
public final boolean parentOf(ThreadGroup g) {
for (; g != null ; g = g.parent) {
if (g == this) {
return true;
}
}
return false;
}
// 确定当前运行的线程是否有权限修改此线程组。 可达性分析
public final void checkAccess() {
// 获得当前的安全管理器
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
// 递归迭代此线程组中的所有子组。返回此线程组及其子组中活动线程数的估计
public int activeCount() {
int result;
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
// 判定当前的线程组是不已经销毁
if (destroyed) {
return 0;
}
result = nthreads;
ngroupsSnapshot = ngroups;
if (groups != null) {
// 将groups存入ngroupsSnapshot
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
// 累计子线程组中的数目
result += groupsSnapshot[i].activeCount();
}
return result;
}
// 将此线程及其子线程中的每个活动线程复制到指定的数组中。
public int enumerate(Thread list[]) {
checkAccess();
return enumerate(list, 0, true);
}
// 将此线程及其子线程中的每个活动线程复制到指定的数组中。
// recurse - 如果 true ,递归枚举此线程组的所有子组
public int enumerate(Thread list[], boolean recurse) {
checkAccess();
return enumerate(list, 0, recurse);
}
// 将此线程及其子线程中的每个活动线程复制到指定的数组中。
// recurse - 如果 true ,递归枚举此线程组的所有子组
private int enumerate(Thread list[], int n, boolean recurse) {
// 存放线程组的数量
int ngroupsSnapshot = 0;
// 存放线程组
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
if (destroyed) {
return 0;
}
// 这里计算list数组中线程的数量
int nt = nthreads;
if (nt > list.length - n) {
nt = list.length - n;
}
// 在list中存入活动的thread
for (int i = 0; i < nt; i++) {
if (threads[i].isAlive()) {
list[n++] = threads[i];
}
}
// recurse - 如果 true ,递归枚举此线程组的所有子组
// 将当前的线程组存入ngroupsSnapshot中
if (recurse) {
ngroupsSnapshot = ngroups;
if (groups != null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
}
// recurse - 如果 true ,递归枚举此线程组的所有子组
if (recurse) {
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n = groupsSnapshot[i].enumerate(list, n, true);
}
}
return n;
}
// 返回此线程组及其子组中活动组数的估计。 递归迭代此线程组中的所有子组。
public int activeGroupCount() {
// 将线程组的数量与组暂存在ngroupsSnapshot, groupsSnapshot中,不影响其它的操作
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
if (destroyed) {
return 0;
}
ngroupsSnapshot = ngroups;
if (groups != null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
int n = ngroupsSnapshot;
// 递归出活动线程组的数量
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n += groupsSnapshot[i].activeGroupCount();
}
return n;
}
// 将此线程组及其子组中的每个活动线程复制到指定的数组中。
public int enumerate(ThreadGroup list[]) {
checkAccess();
return enumerate(list, 0, true);
}
// 将此线程组及其子组中的每个活动线程复制到指定的数组中。
public int enumerate(ThreadGroup list[], boolean recurse) {
checkAccess();
return enumerate(list, 0, recurse);
}
// 将此线程组及其子组中的每个活动线程复制到指定的数组中。
private int enumerate(ThreadGroup list[], int n, boolean recurse) {
// ngroupsSnapshot, groupsSnapshot 分别存放线程组的数量,线程组
int ngroupsSnapshot = 0;
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
if (destroyed) {
return 0;
}
// 计算线程组的数量
// 不懂下面的算法, 为什么要用list.length - n;
int ng = ngroups;
// 传入list的长度是有长度的????
if (ng > list.length - n) {
ng = list.length - n;
}
if (ng > 0) {
// 将当前组中的所有线程组存放在list中,由于list中已经存入了n个元素,所以从n开始
System.arraycopy(groups, 0, list, n, ng);
// n 在这里记录list中活动缓和组的个数
n += ng;
}
if (recurse) {
ngroupsSnapshot = ngroups;
if (groups != null) {
// 将当前线程组中的各个子组暂存在ngroupsSnapshot中
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
}
// 递归调用enumerate(), 计算n;
if (recurse) {
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
//
n = groupsSnapshot[i].enumerate(list, n, true);
}
}
return n;
}
// 已经过期
@Deprecated
public final void stop() {
if (stopOrSuspend(false))
Thread.currentThread().stop();
}
// 中断此线程组中的所有线程
public final void interrupt() {
// ngroupsSnapshot, groupsSnapshot 分别存放线程组的数量,线程组
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
// 校验可过性
checkAccess();
// 组中的线程都调用interrupt()方法,中断线程
for (int i = 0 ; i < nthreads ; i++) {
threads[i].interrupt();
}
ngroupsSnapshot = ngroups;
if (groups != null) {
// 将组暂存ngroupsSnapshot
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
// 递归将所有线程组中的每个线程都调用interrupt()中断
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].interrupt();
}
}
// 已过期
@Deprecated
@SuppressWarnings("deprecation")
public final void suspend() {
if (stopOrSuspend(true))
Thread.currentThread().suspend();
}
// 这个方法只在stop(), suspend()中使用, stop(), suspend() 已经过期,这个方法也相当于过期
@SuppressWarnings("deprecation")
private boolean stopOrSuspend(boolean suspend) {
boolean suicide = false;
Thread us = Thread.currentThread();
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
checkAccess();
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i]==us)
suicide = true;
else if (suspend)
threads[i].suspend();
else
threads[i].stop();
}
ngroupsSnapshot = ngroups;
if (groups != null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++)
suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
return suicide;
}
// 已过期, baiynnnaigh
@Deprecated
@SuppressWarnings("deprecation")
public final void resume() {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
for (int i = 0 ; i < nthreads ; i++) {
threads[i].resume();
}
ngroupsSnapshot = ngroups;
if (groups != null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].resume();
}
}
// 销毁此线程组及其所有子组
public final void destroy() {
// ngroupsSnapshot, groupsSnapshot 分别存放线程组的数量,线程组
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);
}
}
// 添加线程组
private final void add(ThreadGroup g){
synchronized (this) {
// 是否是已经销毁的线程组,抛异常
if (destroyed) {
throw new IllegalThreadStateException();
}
// 如果线程组为空,new 4个长度 的线程组
// 如果当前线程组的长度已满, 则进行扩容
if (groups == null) {
groups = new ThreadGroup[4];
} else if (ngroups == groups.length) {
groups = Arrays.copyOf(groups, ngroups * 2);
}
groups[ngroups] = g;
// 这是最后完成的,因此在线程被杀死时无关紧要
ngroups++;
}
}
// 移除当前的线程组
private void remove(ThreadGroup g) {
synchronized (this) {
// destroyed = true 说明已经销毁了
if (destroyed) {
return;
}
// 从线程组中找到线程组g
for (int i = 0 ; i < ngroups ; i++) {
if (groups[i] == g) {
ngroups -= 1;
// 移除groups[i]
System.arraycopy(groups, i + 1, groups, i, ngroups - i);
groups[ngroups] = null;
break;
}
}
if (nthreads == 0) {
notifyAll();
}
// 如果是守护线程,数量为0, 线程组为0, 没有启动的线程为0 那么销毁所有的线程
if (daemon && (nthreads == 0) &&
(nUnstartedThreads == 0) && (ngroups == 0))
{
destroy();
}
}
}
// 添加没有启动的线程数量, 在Thread中使用一次
void addUnstarted() {
synchronized(this) {
if (destroyed) {
throw new IllegalThreadStateException();
}
nUnstartedThreads++;
}
}
// 添加线程
void add(Thread t) {
synchronized (this) {
// 当前线程组是否已经销毁
if (destroyed) {
throw new IllegalThreadStateException();
}
// 线程数组是否为空,为空则new 4个长度的线程数组
if (threads == null) {
threads = new Thread[4];
// 线程数组已满,则进行扩容
} else if (nthreads == threads.length) {
threads = Arrays.copyOf(threads, nthreads * 2);
}
// 将线程t添加 到threads中
threads[nthreads] = t;
// 线程的数量+1
nthreads++;
// 未启动的线程数量-1
nUnstartedThreads--;
}
}
// 线程启动失败,移除线程,未启动的线程数量+1
void threadStartFailed(Thread t) {
synchronized(this) {
remove(t);
nUnstartedThreads++;
}
}
// 线程已终止
void threadTerminated(Thread t) {
synchronized (this) {
// 移除当前传入的线程
remove(t);
// 这个if 不成立,则下个if必然不成立
// 活动的线程为0的时候, 唤醒所有的线程,便于作进一步的判断是否销毁当前的线程组
if (nthreads == 0) {
notifyAll();
}
if (daemon && (nthreads == 0) &&
(nUnstartedThreads == 0) && (ngroups == 0))
{
destroy();
}
}
}
// 移除线程,
private void remove(Thread t) {
synchronized (this) {
// 当前的线程组已经销毁,则不用移除了
if (destroyed) {
return;
}
// 循环找到thread中的线程t, 并移除
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
// 移除线程t
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
threads[nthreads] = null;
break;
}
}
}
}
// 将有关此线程组的信息打印到标准输出。 此方法仅适用于调试。
public void list() {
list(System.out, 0);
}
//
void list(PrintStream out, int indent) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
for (int j = 0 ; j < indent ; j++) {
out.print(" ");
}
out.println(this);
indent += 4;
for (int i = 0 ; i < nthreads ; i++) {
for (int j = 0 ; j < indent ; j++) {
out.print(" ");
}
out.println(threads[i]);
}
ngroupsSnapshot = ngroups;
if (groups != null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].list(out, indent);
}
}
// 当此线程组中的线程因为一个未捕获的异常由Java Virtual Machine调用
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
@Deprecated
public boolean allowThreadSuspension(boolean b) {
this.vmAllowSuspension = b;
if (!b) {
VM.unsuspendSomeThreads();
}
return true;
}
public String toString() {
return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
}
}