ThreadGroup操作
activeCount()用于获取 group 中活跃的线程,这只是个估计值,并不能百分之百地保证数字一定正确,原因前面已经分析过,该方法会递归获取其他子 group 中的活跃线程。
activeGroupCount()用于获取 group 中活跃的子 group,这也是一个近似估值,该方法也会递归获取所有的子 group。
getMaxPriority()用于获取 group 的优先级,默认情况下,Group 的优先级为10,在该 group 中,所有线程的优先级都不能大于 group 的优先级。
getName()用于获取 group 的名字。
getParent()用于获取 group 的父 group,如果父 group 不存在,则会返回 null,比如 system group 的父 group 就为 null。
list()该方法没有返回值,执行该方法会将 group 中所有的活跃线程信息全部输出到控制台,也就是 System.out。
parentOf(ThreadGroup g)会判断当前 group 是不是给定 group 的父 group,另外如果给定的 group 就是自己本身,那么该方法也会返回 true。
setMaxPriority(int pri)会指定 group 的最大优先级,最大优先级不能超过父 group 的最大优先级,执行该方法不仅会改变当前 group 的最大优先级,还会改变所有子 group 的最大优先级。
public class ThreadGroupBasic{public static void main(String[] args) throws InterruptedException{/** Create a thread group and thread.*/ThreadGroup group = new ThreadGroup("group1");Thread thread = new Thread(group, () ->{while (true){try{TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e){e.printStackTrace();}}}, "thread");thread.setDaemon(true);thread.start();//make sure the thread is startedTimeUnit.MILLISECONDS.sleep(1);ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();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));}}
group.getMaxPriority()=10thread.getPriority()=5group.getMaxPriority()=3thread.getPriority()=5
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();}}
public class ThreadGroupInterrupt{public static void main(String[] args) throws InterruptedException{ThreadGroup group = new ThreadGroup("TestGroup");new Thread(group, () ->{while (true){try{TimeUnit.MILLISECONDS.sleep(2);} catch (InterruptedException e){//received interrupt SIGNAL and clear quicklybreak;}}System.out.println("t1 will exit.");}, "t1").start();new Thread(group, () ->{while (true){try{TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e){//received interrupt SIGNAL and clear quicklybreak;}}System.out.println("t2 will exit.");}, "t2").start();//make sure all of above threads started.TimeUnit.MILLISECONDS.sleep(2);group.interrupt();}}
destroy 用于销毁 ThreadGroup,该方法只是针对一个没有任何 active 线程的 group 进行一次 destroy 标记,调用该方法的直接结果是在父 group 中将自己移除:
Destroys this thread group and all of its subgroups. This thread group must be empty, indicating that all threads that had been in this thread group have since stopped.(销毁 ThreadGroup 及其子 ThreadGroup,在该 ThreadGroup 中所有的线程必须是空的,也就是说 ThreadGroup 或者子 ThreadGroup 所有的线程都已经停止运行,如果有 Active 线程存在,调用 destroy 方法则会抛出异常。)
下面我们写一个简单的代码对其进行测试:
public class ThreadGroupDestroy{public static void main(String[] args){ThreadGroup group = new ThreadGroup("TestGroup");ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();System.out.println("group.isDestroyed=" + group.isDestroyed());mainGroup.list();group.destroy();System.out.println("group.isDestroyed=" + group.isDestroyed());mainGroup.list();}}
程序的运行结果如下所示,其中 isDestroyed 方法是判断 ThreadGroup 是否被 destroy 了:
ggroup.isDestroyed=falsejava.lang.ThreadGroup[name=main,maxpri=10]Thread[main,5,main]Thread[Monitor Ctrl-Break,5,main]java.lang.ThreadGroup[name=TestGroup,maxpri=10]group.isDestroyed=truejava.lang.ThreadGroup[name=main,maxpri=10]Thread[main,5,main]Thread[Monitor Ctrl-Break,5,main]
线程可以设置为守护线程,ThreadGroup 也可以设置为守护 ThreadGroup,但是若将一个 ThreadGroup 设置为 daemon,也并不会影响线程的 daemon 属性,如果一个 ThreadGroup 的 daemon 被设置为 true,那么在 group 中没有任何 active 线程的时候该 group 将自动 destroy,下面我们给出一个简单的例子来对其进行说明:
public class ThreadGroupDaemon{public static void main(String[] args)throws InterruptedException{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("Group2");new Thread(group2, () ->{try{TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e){e.printStackTrace();}}, "group2-thread1").start();//设置 daemon 为 truegroup2.setDaemon(true);TimeUnit.SECONDS.sleep(3);System.out.println(group1.isDestroyed());System.out.println(group2.isDestroyed());}}
在上面的代码中,第二个 group 的 daemon 被设置为 true,当其中没有 active 线程的时候,该 group 将会自动被 destroy,而第一个 group 则相反。




