ThreadGrop详解

2023-01-18 19:47:18

结构思维导图:

                          

构造方法:

public ThreadGroup(String name);//为此线程组赋予名字,但该组的父线程组是创建它的线程所在的线程组

public ThreadGroup(ThreadGroup parent,String name);//第二个构造赋予了线程组名字,同时又显示的指定了组的父线程组

 public static void main(String[] args) {
        ThreadGroup currentGp = Thread.currentThread().getThreadGroup();//当前线程组
        ThreadGroup gp = new ThreadGroup("GP1");
        System.out.println(gp.getParent()==currentGp);//true   gp没显示的指定父线程组,默认为创建它线程所在的线程组
        ThreadGroup gp2 = new ThreadGroup(gp,"GP2");//指定gp为该组的父线程组
        System.out.println(gp2.getParent() == gp);//true
    }

复制ThreadGroup数组:

public int enumerate(ThreadGroup[] list);会将ThreadGroup中的active线程全部复制到Thread数组,等价于(Thread[] true)

public int enumerate(ThreadGroup list,boolean,recurse);会将所有的子group中的active线程递归到Thread数组中

public static void main(String[] args){
    ThreadGroup gp1 = new ThreadGroup("gp1");//父线程是mainGroup
    ThreadGroup gp2 = new ThreadGroup(gp1,"gp2");//父线程是gp1
    TimeUnit.MILLSECONDS.Sleep(2);
    ThreadGroup mainGroup = Thread.currentThread.getThreadGroup();
    ThreadGroup[] list = new ThreadGroup[mainGroup.activeGroupCount()];
    System.out.println(mainGroup.enumerate(list));//递归复制  2 包含了子类的子类
    System.out.println(mainGroup.enumerate(list,false));//1
}

ThreadGroup的基本操作:

1、activeCount()用于获取group中的活跃线程,这只是估值,并不能百分百的保证数字一定正确(递归方法会获取所有的字group)

2、activeGroupCount()用于获取group中的活跃字group,这也是一个估值(该方法会递归所有的子group)

3、getMaxPriority()用于获取group的优先级,默认情况下优先级为10,在group中所有的线程的优先级都不能大于group的优先级

4、getName()获取group名字;getParent()获取group的父group,如果不存在返回null;list()该方法没有返回值执行该方法会将group中所有的活跃的线程信息输出到控制台

5、parentOf(ThreadGroup gp),判断当前group是不是给定group的父group,如果是自己返回true

6、setMaxPrioty(int pri)  会指定group的最大优先级,最大优先级不能超过父group的最大优先级,执行该方法不仅会改变当前group的最大优先级,还会改变所有字group的最大优先级

  public static void main(String[] args) throws InterruptedException{
        ThreadGroup gp = new ThreadGroup("gp1");//该组的父组是创建线程所在的父组,当然也可以显示指定父组(mainGp)
        Thread thread = new Thread(gp,() -> {
            while (true){
                try {
                    TimeUnit.SECONDS.sleep(3);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        },"thread");
        thread.setDaemon(true);
        thread.start();
        TimeUnit.MILLISECONDS.sleep(10);//确保线程已经启动
        ThreadGroup mainGp = Thread.currentThread().getThreadGroup();
        System.out.println("main组的活跃的线程数目:" + mainGp.activeCount());
        System.out.println("main组的活跃的子group数目:" + mainGp.activeGroupCount());
        System.out.println("main组的优先级:" + mainGp.getMaxPriority());
        System.out.println("main组的父组" + mainGp.getParent());
        System.out.println("----------------------------");
        mainGp.list();
        System.out.println("mainGp是不是gp的父组:" + mainGp.parentOf(gp));

    }
控制台输出:
main组的活跃的子group数目:1
main组的优先级:10
main组的父组java.lang.ThreadGroup[name=system,maxpri=10]
----------------------------
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=gp1,maxpri=10]
        Thread[thread,5,gp1]
mainGp是不是gp的父组:true

这里需要注意一点:

1、我将thread线程设为守护线程,jvm检测到没有非守护线程,所以这里jvm会自动退出,若thread先启动在设为守护线程或者已经死亡在设为守护线程会抛出IllegalThreadStateException异常,同时可以看出守护线程具有自动结束生命周期的特点。

2、interrupt一个thread group会导致该group中所有的actie线程都被interrupt,详情请见源码。

ThreadGroup的destory:

destory用于销毁ThreadGroup,该方法只是针对没有任何一个active线程group进行一次标记,调用该方法的直接结果就是在父group中移除自身。(销毁ThreadGroup及其子ThreadGroup,得保证组下的线程必须是停止运行,如果有active线程存在则抛出IllegalThreadStateException)

    public static void main(String[] args) {
        ThreadGroup gp = new ThreadGroup("gp1");
        Thread thread = new Thread(gp,() -> {
            System.out.println("thread启动");
        },"thread");
        //thread.start();
        ThreadGroup mainGp = Thread.currentThread().getThreadGroup();
        mainGp.list();//将该组的所有活跃线程打印
        gp.destroy();
        System.out.println(gp.isDestroyed());
        mainGp.list();
    }

/*    java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    java.lang.ThreadGroup[name=gp1,maxpri=10]
            true
    java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]*/

守护ThreadGroup:

如果将一个group设置为daemon并不会影响线程的daemon,若一个线程组的被设置为守护线程组,那么组中没有任何active线程的时候该组将自动destory。

public static void mian(String[] args){
    ThreadGroup gp1 = new ThreadGroup("GP1");
        new Thread(gp1,() -> {
            System.out.println("thread1");
        },"thread1").start();
        ThreadGroup gp2 = new ThreadGroup("GP2");
        new Thread(gp2,() -> {
            System.out.println("thread2");
        },"thread2").start();
        gp2.setDaemon(true);
        TimeUnit.SECONDS.sleep(3);
        System.out.println(gp1.isDestroyed());//fasle
        System.out.println(gp2.isDestroyed());//true
}

 

  • 作者:蜡笔小ming
  • 原文链接:https://blog.csdn.net/qq_40826106/article/details/86477001
    更新时间:2023-01-18 19:47:18