ThreadGroup线程组源码分析

线程组代表一组线程。 此外,线程组还可以包括其他线程组。 线程组形成一个树,除了初始线程组之外,每个线程组都有一个父进程。

允许线程访问有关其线程组的信息,但不能访问有关其线程组的父线程组或任何其他线程组的信息。

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 + "]";
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值