import java.util.concurrent.TimeUnit;public class Test { public static void main(String[] args){// ThreadGroupCreater.test();// ThreadGroupEnumerateThreads.test();// ThreadGroupEnumerateThreadGroups.test();// ThreadGroupBasic.test();// ThreadGroupInterrupt.test();// ThreadGroupDestroy.test(); ThreadGroupDaemon.test(); }}/* 6.2 创建ThreadGroup public ThreadGroup(String name) public ThreadGroup(ThreadGroup parent, String name) */class ThreadGroupCreater{ public static void test() { ThreadGroup currentGroup = Thread.currentThread().getThreadGroup(); ThreadGroup group1 = new ThreadGroup("Group1"); ThreadGroup group2 = new ThreadGroup(group1,"Group2"); System.out.println(group1.getParent()==currentGroup); System.out.println(group2.getParent()==group1); } /* 6.3.1 复制Thread数组 public int enumerate(Thread[] list) :将ThreadGroup中的所有active线程复制到list中 public int enumerate(Thread[] list,boolean recurse) :将ThreadGroup中的所有active线程复制到list中 如果recurse为true,则递归的将所有子group中的线程也复制到list中 enumerate(Thread[] list)等价与enumerate(Thread[] list, true) enumerate方法的返回值int相较Thread[]的长度更为真实,因为可能受数组长度的限制 导致部分活跃线程数量没有放入数组中。 */}class ThreadGroupEnumerateThreads{ public static void test() { ThreadGroup myGroup = new ThreadGroup("MyGroup"); Thread thread = new Thread(myGroup,()->{ while (true) { try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } },"MyThread"); thread.start(); try { TimeUnit.SECONDS.sleep(2); ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); /* 用法展示在这里: 1.先定义一个数组,通过activeCount方法得到这个数组的长度 2.将这个数组传入到enumerate方法中 3.展示结果。 */ Thread[] list = new Thread[mainGroup.activeCount()]; int recurseSize = mainGroup.enumerate(list); System.out.println(recurseSize); recurseSize = mainGroup.enumerate(list,true); System.out.println(recurseSize); } catch (InterruptedException e) { e.printStackTrace(); } }}/* 6.3.2 复制ThreadGroup数组 public int enumerate(ThreadGroup[] list) public int enumerate(ThreadGroup[] list, boolean recurse) */class ThreadGroupEnumerateThreadGroups{ public static void test() { ThreadGroup myGroup1 = new ThreadGroup("MyGroup1"); ThreadGroup myGroup2 = new ThreadGroup(myGroup1,"MyGroup2"); ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); try { TimeUnit.MILLISECONDS.sleep(2); ThreadGroup[] list = new ThreadGroup[mainGroup.activeCount()]; int recurseSize = mainGroup.enumerate(list); System.out.println(recurseSize); recurseSize = mainGroup.enumerate(list,false); System.out.println(recurseSize); } catch (InterruptedException e) { e.printStackTrace(); } }}/* 6.4.1 ThreadGroup的基本操作 activeCount() :用于获取group中活跃的线程 activeGroupCount() :用于获取group中活跃的子group getName() :用于获取group的名字 getParent() :用于过于group父group的名字 list() :将group中所有活跃线程信息输出到控制台 parentOf() :判断当前group是不是给定group的父group getMaxPriority(): setMaxPriority(): setMaxPriority()只会限制之后加入的线程最大优先级,不会修改加入之前的线程 parentOf()对自生调用这个方法,返回的结果是true */class ThreadGroupBasic { public static void test(){ ThreadGroup group = new ThreadGroup("group"); ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); Thread thread = new Thread(group,()->{ while (true) { try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } },"thread"); thread.setDaemon(true); thread.start(); try { TimeUnit.MILLISECONDS.sleep(1); System.out.println(" activeCount="+mainGroup.activeCount()); System.out.println("activeGroupCount="+mainGroup.activeGroupCount()); System.out.println(" getMaxPriority="+mainGroup.getMaxPriority()); System.out.println(" getName="+mainGroup.getName()); System.out.println(" getParent="+mainGroup.getParent()); mainGroup.list(); System.out.println("================================"); System.out.println("parentOf?"+mainGroup.parentOf(group)); System.out.println("parentOf?"+mainGroup.parentOf(mainGroup)); } catch (InterruptedException e) { e.printStackTrace(); } }}/* 6.4.2 ThreadGroup的interrupt interrupt一个thread group会呆滞该group中所有的active线程都被interrupt。*/class ThreadGroupInterrupt{ public static void test(){ ThreadGroup group = new ThreadGroup("TestGroup"); new Thread(group,()->{ while (true) { try{ TimeUnit.MILLISECONDS.sleep(2); } catch (InterruptedException e) { break; } } System.out.println("t1 will exit..."); },"t1").start(); new Thread(group,()->{ while (true) { try{ TimeUnit.MILLISECONDS.sleep(2); } catch (InterruptedException e) { break; } } System.out.println("t2 will exit..."); },"t2").start(); try { TimeUnit.MILLISECONDS.sleep(3); group.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } }}/* 6.4.3 ThreadGroup的destroy destroy用于销毁ThreadGroup,该方法只是针对一个没有任何active线程的group进行一次 destroy标记,调用该方法的直接结果是在父group中将自己移除。如果有active线程存在,则 会抛出一个错误 */class ThreadGroupDestroy{ public static void test() { ThreadGroup group = Thread.currentThread().getThreadGroup(); System.out.println("group.isDestroyed=" + group.isDestroyed()); group.list(); group.destroy(); System.out.println("group.isDestroyed=" + group.isDestroyed()); group.list(); }}/* 6.4.4 守护ThreadGroup 如果一个ThreadGroup的daemon被设置为true,那么在group中没有任何active线程的时候 该group将自动destroy。 */class ThreadGroupDaemon { public static void test() { ThreadGroup group1 = new ThreadGroup("Group1"); new Thread(group1,()->{ try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } },"group1-thread1").start(); ThreadGroup group2 = new ThreadGroup("Group1"); new Thread(group2,()->{ try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } },"group2-thread1").start(); group2.setDaemon(true); try { TimeUnit.SECONDS.sleep(3); System.out.println(group1.isDestroyed()); System.out.println(group2.isDestroyed()); } catch (InterruptedException e) { e.printStackTrace(); } }}
——《Java高并发编程详解》笔记