[Java 并发]带你从源码解读线程组( ThreadGroup )好不好

ThreadGroup 概念

只是从英文名字上,也能看到这个概念的简单粗暴, ThreadGroup 就是线程组.
也就是说,每个 Thread 都能在一个 ThreadGroup 中找到.那么你可能会问了,我不存在于一个 ThreadGroup 不行?自己在程序里面一个人潇洒走天下,岂不是超级爽?
抱歉,此路不通.为啥呢?咱们来看源码:

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }
    }

我们能够看到,如果 g 为空,会做这样的处理

  • 首先看 security 是否为空,如果不为空,直接使用 security 的线程组
  • 如果 security 是空的话,那么这个线程就获取当前线程所属的线程组
    所以你想脱离组织自己玩?这种事情想都不要想.
    操作系统怎么可能允许有逃离自己掌控之外的存在呢!

优先级

OK ,咱们接下来谈另外一个问题.
一个 Thread 必然存在于一个 ThreadGroup , Thread 有自己的优先级, ThreadGroup 也有优先级,如果 Thread 的优先级大于 ThreadGroup 的优先级了,这个时候咋整呢?

public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        // 如果设置的 priority 大于系统设置的最大值,或者小于系统设置的最小值
        // 抛出异常
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) != null) {
            // 如果设置线程的优先级大于线程组的优先级,则重置线程的优先级为线程组的优先级
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }

所以啊,优先级冲突了,两位也别吵吵, Thread 踏踏实实跟着 ThreadGroup 走才有肉吃不是~

ThreadGroup 还可以做

看完上面,你可能觉得,哦,原来线程组就是管线程的啊
你如果真的这么认为的话,我赶紧写写接下来的内容,把你的思绪拉一拉
线程组管理的可不单单是线程.
咱们看看源码里面,线程组的成员变量都有啥:

public class ThreadGroup implements Thread.UncaughtExceptionHandler {
    private final ThreadGroup parent;  // 父 ThreadGroup
    String name;  // ThreadGroup 名称
    int maxPriority;  // 线程最大优先级
    boolean destroyed;  // 是否被销毁
    boolean daemon;  // 是否守护线程
    boolean vmAllowSuspension;  // 是否可以中断

    int nUnstartedThreads = 0;  // 还未启动的线程
    int nthreads;  // ThreadGroup 中线程数目
    Thread threads[];  // ThreadGroup 中的线程

    int ngroups;  // 线程组数目
    ThreadGroup groups[];  // 线程组数组
}

吼,原来线程组里面还可以有线程组,不单单是有线程,原来还可以控制线程优先级,还可以决定是否销毁线程或者守护线程,或者中断线程.

到这里,咱们来总结一下:

  • 线程组是一个父子结构,一个线程组可以属于其他线程组,也可以拥有自己的子线程组,如果你一直向上追溯的话,会发现所有的线程组都在一个根线程组里面— System 线程组
  • 线程组的出现可不是为耍酷用的,它是为了更方便的管理线程而存在的.比如设置线程最大优先级,销毁线程等等

以上,就是想要分享的内容了
感谢您的阅读哇~

posted @ 2020-05-01 18:14  Developer_lulu  阅读(390)  评论(1编辑  收藏  举报