package java.lang; import java.io.PrintStream; import sun.misc.VM; /** * * 用于处理一组线程的类 * 它是一种树状结构,他的下层节点还可以是ThreadGroup对象 * * comment by liqiang * */ public class ThreadGroup { //父级的线程组对象 ThreadGroup parent; //线程组的名字 String name; //线程组的最大优先级数,线程组所含线程不得超过此值 int maxPriority; boolean destroyed; boolean daemon; boolean vmAllowSuspension; int nthreads; Thread threads[]; int ngroups; ThreadGroup groups[]; /** * * 创建一个空的线程组,它不属于任何线程组,相当于根线程组 * 他的名为system,此方法由c调用 * */ private ThreadGroup() { //设置线程组的名字为system this.name = "system"; //设置线程组的最大优先级,为线程规定的最大优先级 this.maxPriority = Thread.MAX_PRIORITY; } /** * * 构造函数 * */ public ThreadGroup(String name) { //使用当前线程的线程组 this(Thread.currentThread().getThreadGroup(), name); } /** * * 构造函数 * @param parent 父线程组 * @param name 线程组的名字 * */ public ThreadGroup(ThreadGroup parent, String name) { if (parent == null) { throw new NullPointerException(); } //安全检查 parent.checkAccess(); //通过父线程组初始化当前新建的线程组 this.name = name; this.maxPriority = parent.maxPriority; this.daemon = parent.daemon; this.vmAllowSuspension = parent.vmAllowSuspension; this.parent = parent; //将新建线程组加入到父线程组 parent.add(this); } /** * * 返回线程组名 * */ public final String getName() { return name; } /** * * 获得父线程组 * */ public final ThreadGroup getParent() { if (parent != null) parent.checkAccess(); return parent; } /** * * 获得线程组的最大优先级值 * */ public final int getMaxPriority() { return maxPriority; } /** * * 判断当前线程组是否是Daemon * 如果此线程组是Daemon的,如果他的只有一个线程且线程终止 * 或它只有一个线程组,且这个线程组销毁,则当前线程组销毁 * * @return true表示当前线程组是Daemon,false表示不是 */ public final boolean isDaemon() { return daemon; } /** * * 判断当前线程组是否被销毁 * */ public synchronized boolean isDestroyed() { return destroyed; } /** * * 设置线程组的Daemon状态 * @param daemon true表示设置为Daemon线程组,false表示设置为非Daemon线程组 * */ public final void setDaemon(boolean daemon) { checkAccess(); this.daemon = daemon; } /** * * 设置线程组的最大优先级 * @param pri 新的优先级值,比当前对象的线程组最大值小才会被设置,否则被忽略 * */ public final void setMaxPriority(int pri) { int ngroupsSnapshot; ThreadGroup[] groupsSnapshot; synchronized (this) { checkAccess(); if (pri < Thread.MIN_PRIORITY) { //如果比最小优先级小则使用最小优先级 maxPriority = Thread.MIN_PRIORITY; } else if (pri < maxPriority) { //如果设置的优先级比当前线程组的最大值小则 //将它置为当前对象的最大优先级,如果比当前的最大 //优先级大或想的则还使用原来的最大优先级 maxPriority = pri; } ngroupsSnapshot = ngroups; if (groups != null) {//如果此对象有线程组对象 //创建新的线程组数组 groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; //将当前对象中的线程组对象拷贝到新创建的数组中 //做拷贝是为了保证线程安全 System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { //如果当前对象不包含线程组对象,则将groupsSnapshot置为null 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) { //是之地对象的父线程组返回true return true; } } //不是返回false 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) {//如果线程组已被销毁则直接返回0 return 0; } //取得包含的线程数,他是计算所含线程数的基数 result = nthreads; //取得包含的线程组数 ngroupsSnapshot = ngroups; if (groups != null) { //如果包括的子线程组数组不为空,则生成新的线程组数组 //并将当前对象的子线程组拷贝到新建数组中 groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { //将临时变量置为null groupsSnapshot = null; } } //算出所包含所有线程数,线程组包含的线程数与所有子线程组的线程数和 //子线程组的线程数是递归算出的 for (int i = 0 ; i < ngroupsSnapshot ; i++) { result += groupsSnapshot[i].activeCount(); } return result; } /** * * 递归(处理子线程组)的将当前线程组中的所有Alive线程对象 * 拷贝到List中 * */ public int enumerate(Thread list[]) { checkAccess(); return enumerate(list, 0, true); } /** * * 将当前线程组中的所有Alive线程对象拷贝到List中 * * @param list 拷贝的目标数组 * @param recurse 表示是否处理子线程组中的线程对象 */ public int enumerate(Thread list[], boolean recurse) { checkAccess(); return enumerate(list, 0, recurse); } //将当前线程组中的Alive线程个数拷贝到list中, //n为开始填充的位置,recurse表示是否递归处理 //表示是否递归读取子线程组Alive的线程对象 private int enumerate(Thread list[], int n, boolean recurse) { int ngroupsSnapshot = 0; ThreadGroup[] groupsSnapshot = null; synchronized (this) { if (destroyed) {//如果线程组被销毁则返回0 return 0; } int nt = nthreads; if (nt > list.length - n) { //如果空余个数比所含线程数大,则使用空余个数 nt = list.length - n; } //将Alive的线程对象放到数组的相应位置 for (int i = 0; i < nt; i++) { if (threads[i].isAlive()) { list[n++] = threads[i]; } } if (recurse) {//如果需要处理子线程数组的线程对象 ngroupsSnapshot = ngroups; //如果当前线程组数组不为null //生成新的线程组数组,并将当前线程组对象拷贝到新建线程组数组 if (groups != null) { groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { groupsSnapshot = null; } } } if (recurse) { //如果处理子线程数组,则递归的将子线程数组的Alive的 //线程对象拷贝到数组中 for (int i = 0 ; i < ngroupsSnapshot ; i++) { n = groupsSnapshot[i].enumerate(list, n, true); } } //返回获取的线程个数 return n; } /** * * 判断当前线程组中线程组的个数 * 是递归计算的(计算子线程组中的个数,依次向下) * */ public int activeGroupCount() { int ngroupsSnapshot; ThreadGroup[] groupsSnapshot; synchronized (this) { if (destroyed) { return 0; } ngroupsSnapshot = ngroups; //如果当前线程组数组不为null //生成新的线程组数组,并将当前线程组对象拷贝到新建线程组数组 if (groups != null) { groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { groupsSnapshot = null; } } int n = ngroupsSnapshot; //递归计算 for (int i = 0 ; i < ngroupsSnapshot ; i++) { n += groupsSnapshot[i].activeGroupCount(); } return n; } /** * * 递归的将当前线程组中包含的线程组拷贝到list中 * */ public int enumerate(ThreadGroup list[]) { checkAccess(); return enumerate(list, 0, true); } /** * * 将当前线程组中包含的线程组拷贝到list中 * @param list 拷贝的目标数组 * @param recurse true表示递归处理,fale不递归处理 * 递归处理指递归拷贝每个子线程组中的子线程组 */ public int enumerate(ThreadGroup list[], boolean recurse) { checkAccess(); return enumerate(list, 0, recurse); } //将当前线程组中包含的线程组拷贝到list中 //表示其实位置,recurse为true表示递归处理,fale不递归处理 //递归处理指递归拷贝每个子线程组中的子线程组 private int enumerate(ThreadGroup list[], int n, boolean recurse) { int ngroupsSnapshot = 0; ThreadGroup[] groupsSnapshot = null; synchronized (this) { if (destroyed) { //如果此线程组已被销毁则直接返回0 return 0; } int ng = ngroups; if (ng > list.length - n) { //计算将要填充的个数,输入数组的剩余长度 //比所含的线程数组个数小,则只填充剩余长度个数的线程数组元素 ng = list.length - n; } //将所含的线程组拷贝到list中 if (ng > 0) { System.arraycopy(groups, 0, list, n, ng); n += ng; } if (recurse) {//如果计算子线程组 ngroupsSnapshot = ngroups; if (groups != null) { //生成新的线程组,并将原线程组元素拷贝到新线程组中 groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { groupsSnapshot = null; } } } 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() { int ngroupsSnapshot; ThreadGroup[] groupsSnapshot; synchronized (this) { checkAccess(); //中断当前线程组下的线程 for (int i = 0 ; i < nthreads ; i++) { threads[i].interrupt(); } ngroupsSnapshot = ngroups; //如果当前线程组包含子线程组 //生成新的线程组,并将原线程组元素拷贝到新线程组中 if (groups != null) { groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { groupsSnapshot = null; } } //递归中断每个子线程组下的线程,和其线程组中的线程 for (int i = 0 ; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].interrupt(); } } /** * * 挂起线程组树中的所有线程,不建议被使用 * @deprecated * */ public final void suspend() { //挂起线程组树中的所有线程 //如果线程组树中包括当前对象则挂起当前对象 if (stopOrSuspend(true)) Thread.currentThread().suspend(); } /** * * 挂起或中断当前线程组树中的所有线程,如果包括当前线程, * 则不做处理,但是返回自杀标记 * suspend为true表示为挂起操作,为false表示为停止操作 * **/ 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)//如果此线程对象是自己,则标志自杀位为true suicide = true; else if (suspend)//suspend为true,做挂起处理 threads[i].suspend(); else//suspend为false做停止处理 threads[i].stop(); } ngroupsSnapshot = ngroups; //如果当前线程组包含子线程组 //生成新的线程组对象,并将当前线程组对象拷贝到数组中 if (groups != null) { groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } } //递归处理子线程组,有一个线程组为自杀状态则标志为自杀状态 for (int i = 0 ; i < ngroupsSnapshot ; i++) suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide; return suicide; } /** * * 唤醒线程组树中的所有线程,不建议被使用 * @deprecated * */ 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 = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { groupsSnapshot = null; } } //递归唤醒每个子线程组下的线程,和其线程组中的线程 for (int i = 0 ; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].resume(); } } /** * * 销毁线程组中的每个子线程组 * */ public final void destroy() { int ngroupsSnapshot; ThreadGroup[] groupsSnapshot; synchronized (this) { checkAccess(); if (destroyed || (nthreads > 0)) { //如果已经被销毁,或当前线程组没有活动线程则抛出异常 throw new IllegalThreadStateException(); } ngroupsSnapshot = ngroups; if (groups != null) { //如果当前线程组包含子线程组 //生成新的线程组对象,并将当前线程组对象拷贝到数组中 groupsSnapshot = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { //将表示子线程组的数组置空 groupsSnapshot = null; } if (parent != null) { //表示不是System线程组,做清楚操作 destroyed = true; ngroups = 0; groups = null; nthreads = 0; threads = null; } } //递归销毁每个子线程组下的线程组 //注意ngroupsSnapshot为0是递归的终止条件 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(); } if (groups == null) { //如果线程组中没有子线程组,则生成新的线程组数组 groups = new ThreadGroup[4]; } else if (ngroups == groups.length) {//如果已满 //生成原来2倍大长度的线程组数组,并将原线程组元素拷贝到新数组中 ThreadGroup newgroups[] = new ThreadGroup[ngroups * 2]; System.arraycopy(groups, 0, newgroups, 0, ngroups); //新数组置为当前线程组数组变量 groups = newgroups; } //将此线程组加入到子线程组数组中 //注意ngroups表示个数,在数组中表示下一个插入的位置 groups[ngroups] = g; //子线程组个数加1 ngroups++; } } /** * * 从当前线程组中删除指定子线程组 * */ private void remove(ThreadGroup g) { synchronized (this) { if (destroyed) {//如果当前线程组已经销毁则直接返回 return; } for (int i = 0 ; i < ngroups ; i++) {//轮循子线程组 if (groups[i] == g) { //如果找到此线程组元素,则长度减1,数组从此位置后一位向前移动 //使得在数组中清除此元素 ngroups -= 1; System.arraycopy(groups, i + 1, groups, i, ngroups - i); //将最后一个元素置为null groups[ngroups] = null; //清除成功跳出循环 break; } } if (nthreads == 0) { notifyAll(); } if (daemon && (nthreads == 0) && (ngroups == 0)) { //如果当前线程是daemo,且没有线程和线程组,则销毁此线程组 destroy(); } } } /** * * 向线程组中添加线程 * */ void add(Thread t) { synchronized (this) { if (destroyed) {//如果线程组已经销毁则抛出异常 throw new IllegalThreadStateException(); } if (threads == null) { //如果当前线程组没有此线程,则创建存放线程的数组 threads = new Thread[4]; } else if (nthreads == threads.length) { //如果存线程的数组已满,则创建一个新的线程数组 //长度为原来的2倍,并将原来的线程对象拷贝到新建数组中 Thread newthreads[] = new Thread[nthreads * 2]; System.arraycopy(threads, 0, newthreads, 0, nthreads); threads = newthreads; } //将要添加的线程对象添加到数组中 threads[nthreads] = t; //线程个数加1 nthreads++; } } /** * * 删除当前线程组中的指定线程(不做递归) * */ void remove(Thread t) { synchronized (this) { if (destroyed) {//如果线程组已经销毁则直接返回 return; } for (int i = 0 ; i < nthreads ; i++) { if (threads[i] == t) { //如果找到此线程元素,则长度减1,数组从此位置后一位向前移动 //使得在数组中清除此元素 System.arraycopy(threads, i + 1, threads, i, --nthreads - i); threads[nthreads] = null; //清除成功跳出循环 break; } } if (nthreads == 0) { notifyAll(); } //如果当前线程是daemo,且没有线程和线程组,则销毁此线程 if (daemon && (nthreads == 0) && (ngroups == 0)) { destroy(); } } } /** * * 在标准输出(System.out)中打印出线程组中的信息 * 此方法用于调试 * */ public void list() { list(System.out, 0); } /** * * 向流中打印线程组中的信息 * * @param out PrintStream的流 * @param indent 缩进数 * */ void list(PrintStream out, int indent) { int ngroupsSnapshot; ThreadGroup[] groupsSnapshot; synchronized (this) { //打印出indent个空格用来表示缩进 for (int j = 0 ; j < indent ; j++) { out.print(" "); } //toString方式 out.println(this); //做4个缩进 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 = new ThreadGroup[ngroupsSnapshot]; System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot); } else { //如果没有子线程组,groupsSnapshot初始化为null groupsSnapshot = null; } } //将子线程组中的信息(递归得到)打印到流中 for (int i = 0 ; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].list(out, indent); } } /** * 当线程组由于未处理异常停止时,此方法被虚拟机调用 * 如果此线程组有父线程组则调用父线程组的此方法 * 如果没有父线程组,判断如果此线程不是ThreadDeath则打印出异常 * */ public void uncaughtException(Thread t, Throwable e) { if (parent != null) {//如果有父线程组,则递归调有父线程组的此方法 parent.uncaughtException(t, e); } else if (!(e instanceof ThreadDeath)) { //如果线程不是ThreadDeath则打印出异常 e.printStackTrace(System.err); } } /** * @deprecated */ public boolean allowThreadSuspension(boolean b) { this.vmAllowSuspension = b; if (!b) { VM.unsuspendSomeThreads(); } return true; } /** * * 线程组的字符串表示形式 * 一个示例java.lang.ThreadGroup[name=main,maxpri=10] */ public String toString() { return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]"; } } 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liqj2ee/archive/2006/01/16/581220.aspx