• 多线程源码--ThreadGroup源码


    前言

      线程组,顾名思义,就是线程的组,逻辑类似项目组,用于管理项目成员,线程组就是用来管理线程。

      每个线程都会有一个线程组,如果没有设置将会有些默认的初始化设置

      而在java中线程组则是使用类ThreadGroup 进行抽象描述

    构造器

      

    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 final ThreadGroup parent; //父线程组
    String name;  //线程名称
    int maxPriority;  //最大优先级
    boolean destroyed;  //是否销毁
    boolean daemon;  //是否为守护
    boolean vmAllowSuspension;
    
    int nUnstartedThreads = 0; //未启动线程数
    int nthreads;  //线程总数
    Thread threads[]; //线程数组
    
    int ngroups; //线程组数量
    ThreadGroup groups[]; //线程组数组

    方法

    Get / Set 方法

    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 boolean parentOf(ThreadGroup g) {  //当前线程组 是否 为线程组g的父线程组

       for (; g != null ; g = g.parent) {

         if (g == this) {

           return true;

         }

       } return false;

    }

    //设置最大优先级

    public final void setMaxPriority(int pri) {
      int ngroupsSnapshot;
      ThreadGroup[] groupsSnapshot;
      synchronized (this) {
        checkAccess();  //权限效验
        if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {  //必须在范围之内
          return;
        }

          //父线程不为空,选择参数pri和父线程组最大优先级中最小的;否则为参数pri
        maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri; 
        ngroupsSnapshot = ngroups;//线程组数赋值
        if (groups != null) { //线程数组不为空
          groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot); //线程组复制
        } else {
          groupsSnapshot = null;
        }
      }

        //设置所有线程组最大优先级
      for (int i = 0 ; i < ngroupsSnapshot ; i++) {
        groupsSnapshot[i].setMaxPriority(pri);
      }
    }

    enumerate()方法:把此线程组中的所有活动子组的引用复制到指定线程数组中。

    public int enumerate(Thread list[]) {
            checkAccess();
            return enumerate(list, 0, true);
        }
    public int enumerate(Thread list[], boolean recurse) {
            checkAccess();
            return enumerate(list, 0, recurse);
        }
    private int enumerate(Thread list[], int n, boolean recurse) {
            int ngroupsSnapshot = 0;
            ThreadGroup[] groupsSnapshot = null;
            synchronized (this) {
                if (destroyed) { //如果销毁,退出
                    return 0;
                }
                int nt = nthreads;//将线程数赋值给nt
                if (nt > list.length - n) {  //如果nt大于它,就将其设置为它。
                    nt = list.length - n;
                }
             //将线程组中的线程,赋值给list线程集合
                for (int i = 0; i < nt; i++) {
                    if (threads[i].isAlive()) {
                        list[n++] = threads[i];
                    }
                }
                if (recurse) {
                    ngroupsSnapshot = ngroups;
                    if (groups != null) {
                        groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
                    } else {
                        groupsSnapshot = null;
                    }
                }
            }
            if (recurse) {
                for (int i = 0 ; i < ngroupsSnapshot ; i++) {
                    n = groupsSnapshot[i].enumerate(list, n, true);
                }
            }
            return n;
        }

    enumerate()方法:把此线程组中的所有活动子组的引用复制到指定线程数组中

    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) {
            int ngroupsSnapshot = 0;
            ThreadGroup[] groupsSnapshot = null;
            synchronized (this) {
                if (destroyed) {
                    return 0;
                }
                int ng = ngroups;
                if (ng > list.length - n) {
                    ng = list.length - n;
                }
                if (ng > 0) {
                    System.arraycopy(groups, 0, list, n, ng);
                    n += ng;
                }
                if (recurse) {
                    ngroupsSnapshot = ngroups;
                    if (groups != null) {
                        groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
                    } else {
                        groupsSnapshot = null;
                    }
                }
            }
            if (recurse) {
                for (int i = 0 ; i < ngroupsSnapshot ; i++) {
                    n = groupsSnapshot[i].enumerate(list, n, true);
                }
            }
            return n;
        }

    统计活动线程/线程组估计数

    //活动线程估计数
    public int activeCount() {
            int result;
            int ngroupsSnapshot;
            ThreadGroup[] groupsSnapshot;
            synchronized (this) {
                if (destroyed) {
                    return 0;
                }
                result = nthreads;
                ngroupsSnapshot = ngroups;
                if (groups != null) {
                    groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
                } else {
                    groupsSnapshot = null;
                }
            }
            for (int i = 0 ; i < ngroupsSnapshot ; i++) {
                result += groupsSnapshot[i].activeCount();
            }
            return result;
        }
    //活动线程组的估计数
    public int activeGroupCount() {
            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;
        }

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

    destory() 销毁此线程组及其所有子组。

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

    add()  将指定的线程组添加到此组。

    private final void add(ThreadGroup g){
            synchronized (this) {
                if (destroyed) {
                    throw new IllegalThreadStateException();
                }
                if (groups == null) { //线程组数组为空,新建长度为4
                    groups = new ThreadGroup[4];
                } else if (ngroups == groups.length) { //不为空,扩容2倍
                    groups = Arrays.copyOf(groups, ngroups * 2);
                }
                groups[ngroups] = g;
                ngroups++; //线程组数量自增1
            }
        }

    remove() 从该组中移除指定的线程组。

    private void remove(ThreadGroup g) {
            synchronized (this) {
                if (destroyed) {
                    return;
                }
                for (int i = 0 ; i < ngroups ; i++) {
              //循环找到线程组中指定的线程,进行移除操作
    if (groups[i] == g) { ngroups -= 1; System.arraycopy(groups, i + 1, groups, i, ngroups - i); groups[ngroups] = null; break; } }
            //如果当前线程组内无线程,唤醒其他所有线程
    if (nthreads == 0) { notifyAll(); }
           //此线程组啥都没有了,就销毁
    if (daemon && (nthreads == 0) && (nUnstartedThreads == 0) && (ngroups == 0)) { destroy(); } } }

    还有一些方法没有介绍到,可以结合源码进行详细学习。

  • 相关阅读:
    【Flutter学习】之绘画实例(二)
    【Flutter学习】之绘画实例(一)
    【Flutter学习】之动画实现原理浅析(三)
    【Flutter学习】之动画实现原理浅析(二)
    NopCommerce支持多种类型的数据库
    NopCommerce 多数据库方案
    开发程序需要注意的点
    基于SVN的项目管理——集中与分散
    JS代码优化小技巧
    开发日记:中控PUSH协议
  • 原文地址:https://www.cnblogs.com/FondWang/p/12100517.html
Copyright © 2020-2023  润新知