线程一1.0 线程 ThreadGroup

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/insis_mo/article/details/88638106

ThreadGroup和Thread 、

在Java程序中,默认,新的线程会被加入main所在的group中,main线程的group名字同线程名,如同线程存在父子关系一样,threadgroup同样也存在父子关系,下图说明了父子thread,父子threadGroup 以及thread和group之间的层次关系:

无论如何线程都会被加入到某个threadgroup中。

二: 创建threadgroup;

语法:public threadgroup(string name)

      public threadGroup (ThreadGroup parent, string name)

创建threadGroup非常简单,通过上面构造函数就行,

public static void main(String[] args) {
    //获取当前线程的group
    ThreadGroup currentGroup=Thread.currentThread().getThreadGroup();
    //定义一个新的group
    ThreadGroup group1 = new ThreadGroup("Group1");
    System.out.println(group1.getParent()==currentGroup);
    //定义一个group2,指定group1为其父group
    ThreadGroup group2 = new ThreadGroup(group1,"Group2");
    System.out.println(group2.getParent()==group2);
}
}
结果:

true

true

 三复制thread 和threadgroup 数组

先看如下两个方法:

 public int enumerate(Thread [] list)

 public int enumerate(Thread [] list ,boolean recurse)

上面两个方法会将threadGroup中的active线程全部复制到thread数组中。其中recurse参数为true的话,则该方法会将所有的子group中的active线程都递归到thread数组中,

测试一下:

public static void main(String[] args) throws InterruptedException {
    //定义一个新的group
    ThreadGroup myGroup  = new ThreadGroup("myThreadGroup");
    Thread thread =new Thread(myGroup,()->{
        while(true) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    } ,"myThread");
    thread.start();
    TimeUnit.MILLISECONDS.sleep(2);
    ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
    Thread []list = new  Thread[mainGroup.activeCount()];
    int recurseSize = mainGroup.enumerate(list);
            System.out.println(recurseSize);
            recurseSize=mainGroup.enumerate(list, false);
            System.out.println(recurseSize);
    }
}

输出最后一个比第一个少1,因为代码中将recurse设置为了false,myGroup将不会包含在内

复制threadgroup 数组

public  interruptenumerate(threadgroup【】 list)

public int enumerate(threadGroup [] list ,boolean recurse)

和复制thread 类似,上面方法主要用于复制当前Threadgroup 的子group, 同样recurse会决定是否以递归的方式复制。

public static void main(String[] args) throws InterruptedException {
    //定义一个新的group
    ThreadGroup myGroup1  = new ThreadGroup("myGroup1");
    ThreadGroup myGroup2  = new ThreadGroup(myGroup1,"myGroup2");
    TimeUnit.MILLISECONDS.sleep(2);
    ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
    ThreadGroup [] list=new ThreadGroup[mainGroup.activeCount()];
    int recurseSize=mainGroup.enumerate(list);
    System.out.println(recurseSize);
    recurseSize=mainGroup.enumerate(list, false);
System.out.println(recurseSize);
}
}
上面代码,mygroup1 的父group 为mainGroup,而mygroup2的父group为myGroup1,因此运行后,递归复制结果为2,不递归结果为1

三  threadgroup的interrupt

interrupt 一个threadgroup 会导致该group中所有的active线程都被interrupt,也就是该group的没一个线程的interrupt标识都被设置了,下面是threadgroup的interrupt源码:

interrupt内部会执行所有的thread的interrupt方法,并且会递归获取子group,然后执行他们各自的interrupt方法,测试一下:

public static void main(String[] args) throws InterruptedException {
    //定义一个新的group
    ThreadGroup myGroup1  = new ThreadGroup("TestGroup");
    new Thread(myGroup1,()-> {
        while(true) {
            try {
                TimeUnit.MILLISECONDS.sleep(2);
            } catch (Exception e) {
                // TODO: handle exception
                break;
            }
        }
        System.out.println("t1 will exit,");
    },"t1").start();
    new Thread(myGroup1,()-> {
        while(true) {
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (Exception e) {
                // TODO: handle exception
                break;
            }
        }
        System.out.println("t2 will exit,");
    },"t2").start();
    TimeUnit.MILLISECONDS.sleep(2);
    myGroup1.interrupt();
}
}

结果,group中的active thread都将被interrupt

四: threadgroup中的destroy

 destroy 用于销毁threadgroup,该方法只是针对一个没有任何active线程的group进行一次destroy 标记,调用改方法的直接结果及时在父group中将自己移除,

测试一下:

public static void main(String[] args) throws InterruptedException {
    //定义一个新的group
    ThreadGroup myGroup1  = new ThreadGroup("TestGroup");
    ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
    System.out.println("group .isDestroyed="+myGroup1.isDestroyed());
    mainGroup.list();
    myGroup1.destroy();
    System.out.println("group.isdestroyed="+myGroup1.isDestroyed());
    mainGroup.list();
}

结果如下:

五,守护threadgroup

线程可以设置为守护线程,threadgroup也可以设置为守护threadgroup,但是若将一个threadgroup设置为daemon,也并不会影响线程的daemon属性,如果一个threadgroup的daemon被设置为true,那么在group中没有任何active线程的时候该group将自动destroy,测试一下:

public class ThreadGroupCreator {
public static void main(String[] args) throws InterruptedException {
    //定义一个新的group
    ThreadGroup myGroup1  = new ThreadGroup("group1");
    new Thread(myGroup1,()->{
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            // TODO: handle exception
        }
    },"group1-thread").start();
    ThreadGroup myGroup2  = new ThreadGroup("group2");
    new Thread(myGroup2,()->{
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            // TODO: handle exception
        }
    },"group2-thread").start();
    myGroup2.setDaemon(true);
    TimeUnit.SECONDS.sleep(3);
    System.out.println(myGroup1.isDestroyed());
    System.out.println(myGroup2.isDestroyed());
    
}
}
第二个group的daemon被设置为true,当其中没有active线程的时候,改group将会被自动destroy,而第二个则不会

猜你喜欢

转载自blog.csdn.net/insis_mo/article/details/88638106