ThreadGroup 朱雀 2020-05-12 16:09 771阅读 0赞 # ThreadGroup **1 ThreadGroup简介** 线程组(`ThreadGroup`)表示一个线程的集合。此外,线程组也可以包含其他线程组。**线程组构成一棵树**,在树中,除了初始线程组(system)外,每个线程组都有一个父线程组。 允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。 每一个线程产生时,都会被归入某个线程组,视线程是在哪个线程组中产生而定。**如果没有指定,则归入产生该子线程的线程的线程组中**。 ThreadGroup类正如其名,可以统一管理整个线程组中的线程,ThreadGroup中的某些方法,可以对所有的线程产生作用,例如`interrupt`()方法可以interrupt线程组中所有的线程。 当一个应用启动时,默认会创建两个线程组,`system`线程组和`main`线程组。其中system线程组是main线程组的父线程组。 system线程组是JVM工作过程中,可能需要一些线程,例如垃圾回收线程,信号转发线程。 main线程组,主要用户创建的线程,如果开发者在创建线程的时候,没有指定线程组,那么就会归于main线程组。 ```java public class ThreadGroupDemo { public static void main(String[] args) { Thread t1=new Thread(){ @Override public void run() { try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } }; t1.start(); ThreadGroup threadGroup = t1.getThreadGroup(); System.out.println(threadGroup); ThreadGroup systemThreadGroup = threadGroup.getParent(); System.out.println(systemThreadGroup); systemThreadGroup.list();//列出线程组树形结构,只会打印出已经start的线程信息 } } ``` 上述代码运行后,会输出树状线程组结构: ```java java.lang.ThreadGroup[name=main,maxpri=10] java.lang.ThreadGroup[name=system,maxpri=10] Thread[Reference Handler,10,system] Thread[Finalizer,8,system] Thread[Signal Dispatcher,9,system] Thread[Attach Listener,5,system] java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main] Thread[Monitor Ctrl-Break,5,main] Thread[Thread-0,5,main] ``` ## 2 为什么要使用ThreadGroup ThreadGroup在实际开发中使用的较少。在<<THE JavaTM Programming Language, Fourth Edition>>一书的14.11节中,提到了为什么要引入线程组这个概念: ![](/images/1589299708471.jpg) 相关内容截图如下所示: ![](/images/1589299676599.png) 可以看到,引入ThreadGroup主要是2个原因:**管理和安全**。 ## 2.1 管理 ThreadGroup提供了多个方法方面我们对线程进行统一的管理。您可以使用以下方式来产生线程组,也可以自行指定线程组,线程一旦归入某个组,就无法更换组。 ```java public Thread(ThreadGroup group, String name) ``` 下面是一个简单的案例: - 通过ThreadGroup的`activeCount`获取当前活跃的线程 - 通过ThreadGroup的`interrupt`方法中断所有的线程 ```java public class ThreadGroupDemo2 { static class SleepTask implements Runnable { @Override public void run() { try { TimeUnit.HOURS.sleep(1);// 休眠1小时 } catch (InterruptedException e) { //ignore } } } public static void main(String[] args) { ThreadGroup threadGroup = new ThreadGroup("group"); Thread thread1 = new Thread(threadGroup, new SleepTask(), "thread1"); Thread thread2 = new Thread(threadGroup, new SleepTask(), "thread2"); //activeCount方法用于返回当前活跃的线程,因为刚创建时2个线程都没有启动因此返回0 assert threadGroup.activeCount() == 0; thread1.start(); thread2.start(); //线程组中的2个线程都启动了,active为2 assert threadGroup.activeCount() == 2; threadGroup.interrupt(); //中断之后,active为0 assert threadGroup.activeCount() == 0; } } ``` ThreadGroup还有有一些其他方法,实际开发中基本也很少使用。唯一值得一说的是ThreadGroup实现了`Thread.UncaughtExceptionHandler`接口: ```java public interface UncaughtExceptionHandler { void uncaughtException(Thread t, Throwable e); } ``` 在JDK5.0中,可以为任何一个Thread设置一个UncaughtExceptionHandler,通过调用Thread类的setUncaughtExceptionHandler方法: ```java public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) ``` 其作用是当某个线程执行某段代码出现未捕获的异常而停止了,可以通过这个UncaughtExceptionHandler对这个异常进行处理,例如记录错误日志。 当然你也可以为所有Thread设置一个全局的默认UncaughtExceptionHandler,通过调用Thread类的静态方法 ```java public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) ``` 通常不建议使用,实际开发中,代码都是由多个模块组成的,例如两个模块的开发人员都要设置全局的UncaughtExceptionHandler,那么就有了冲突。最好的办法就是不设置全局的,只对这个模块创建的线程进行单独设置。 **需要注意的是:** 当线程有未捕获的异常,在回调UncaughtExceptionHandler的uncaughtException方法时,线程已经停止了。这个时候对异常进行处理,其实作用也不大,毕竟线程停止已经没法继续处理任务了。 当然你可以进行补救,例如创建一个新的线程来运行任务。 **这里不得不提ThreadGroup与线程池(ThreadPoolExecutor)的区别:** **ThreadGroup:**管理的是线程,需要手工创建线程添加到ThreadGroup中 **线程池:**管理的是线程+任务。我们可以指定线程池的核心线程数,最大线程数,以及任务队列等。当某个线程出现未捕获的异常而中断时,线程池也可以自动帮我们来创建新的线程,这是通过线程工厂(ThreadFactory来实现的)。 所以,千万不要把ThreadGroup和线程池放到同一个层面来进行比较,二者的关注点本来就不同。一个关注的是对线程的管理,一个关注的是如何维护指定数量的线程来运行任务。 事实上,因为一个线程池中通常都是运行同一类任务,所以我们可以把一个线程池中创建的所有线程都放到同一个ThreadGroup中。之后在线程池需要停止的时候,可以利用ThreadGroup的一些管理方法,如interrupt,来中断所有的线程。 ## 2.2 安全 引入ThreadGroup的另外一个原因:安全。Java支持在运行时对代码运行执行的操作执行一些安全性检查工作,一些涉及到安全性的操作,都有对应的权限(`Permission`)来描述。Permission有很多,如下: ![](/images/1589299649063.png) 其中: `BasicPermission`有一个子类`RuntimePermission`,表示运行时的权限检查。完整的权限信息请参考RuntimePermission的javadoc,我们仅仅关注于Thread和ThreadGroup相关的权限。 ![](/images/1589299626167.png) 可以看到,关于Thread和ThreadGroup相关的权限是:modifyThread、stopThread、modifyThreadGroup,关于这三个权限的说明和可能存在的安全问题,参考表格后面的说明。 使用步骤通常如下所示: **1、创建一个安全策略文件** 在/test目录下创建一个runtime.policy文件(名字随意,通常以.policy结尾) ```plain grant codeBase "file:/C:/classes/remote/*" { permission java.lang.RuntimePermission "modifyThread,stopThread,modifyThreadGroup"; }; ``` **2、启动java程序时指定jvm参数指定使用安全管理器,并指定策略文件的位置** 如: ```plain java -Djava.security.manager -Djava.security.policy=/test/runtime.policy 主类 ``` 最后提示: Java Security的权限管理只有一些极端特殊的项目才有可能使用到,绝大部分情况下是鸡肋。也建议读者非工作需要的话,没有必要去研究这个,因为研究了也用不上,一些人可能一辈子也用不上… # 3 总结 ThreadGroup两大功能:对线程管理和安全,在实际开发中直接使用的比较少,一般我们都是直接使用线程池。
相关 ThreadGroup解读 我们的项目用到了ThreadGroup 把thread放到了threadGroup中,名称统一起来了; ![复制代码][48304ba5e6f9fe08f3fa1abda7d 偏执的太偏执、/ 2022年12月29日 12:54/ 0 赞/ 175 阅读
相关 Java线程组-ThreadGroup 1、什么是线程组 ThreadGroup类是线程组,表示一组线程的集合,可用其对一批线程和线程组进行管理。可把线程归属到指定的线程组中,线程组中可以有线程对象,也可以有线 小灰灰/ 2022年09月15日 00:58/ 0 赞/ 174 阅读
相关 Java线程组ThreadGroup 摘要:线程组ThreadGroup表示一组线程的集合,一旦一个线程归属到一个线程组之中后,就不能再更换其所在的线程组。那么为什么要使用线程组呢?个人认为有以下的好处:方便统一 我会带着你远行/ 2022年05月15日 08:13/ 0 赞/ 400 阅读
相关 Java高并发编程详解系列-ThreadGroup介绍 > 在之前的分享中提到过关于Thread的部分源码分析,其中提到的一个比较关键的概念就是关于ThreadGroup的概念,也就是说每个一个线程创建之后都会属于一个线程组。每个线 我不是女神ヾ/ 2022年04月25日 05:14/ 0 赞/ 459 阅读
相关 java ThreadGroup 作用 方法解析 闲来无事 写篇博客。 ThreadGroup线程组,java对这个类的描述呢就是 “线程组表示一组线程。此外,线程组还可以包括其他线程组。线程组形成一个树,其中除了初始 太过爱你忘了你带给我的痛/ 2022年03月19日 10:37/ 0 赞/ 260 阅读
相关 Java并发基础(八)——线程组(ThreadGroup)与守护线程(Daemon) 线程组(ThreadGroup) 在一个系统中,如果线程数量很多,而且功能分配比较明确,就可以将相同功能的线程放置在同一个线程组里。下面通过示例来说明。 迈不过友情╰/ 2022年03月17日 03:30/ 0 赞/ 269 阅读
相关 Java并发编程与技术内幕:ThreadGroup线程组应用 [https://blog.csdn.net/evankaka/article/details/51627380][https_blog.csdn.net_evankaka_a 我不是女神ヾ/ 2021年09月16日 00:46/ 0 赞/ 375 阅读
相关 Java并发编程与技术内幕:ThreadGroup线程组应用 林炳文Evankaka原创作品。转载请注明出处[http://blog.csdn.net/evankaka][http_blog.csdn.net_evankaka] 太过爱你忘了你带给我的痛/ 2021年09月11日 00:10/ 0 赞/ 616 阅读
相关 ThreadGroup 线程组(`ThreadGroup`)表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组(system)外,每个线程组都有一个父... 朱雀/ 2020年05月12日 16:09/ 0 赞/ 772 阅读
还没有评论,来说两句吧...