image.png

一、什么是线程组

线程组ThreadGroup表示一组线程的集合。可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,这样的组织结构有点类似于树的形式。
通常情况下根线程组是system线程组。system线程组下是main线程组,默认情况下第一级应用自己的线程组是通过main线程组创建出来的。

二、线程组的作用

ThreadGroup是为了方便线程管理出现了,可以统一设定线程组的一些属性,比如setDaemon,设置未处理异常的处理方法,设置统一的安全策略等等;也可以通过线程组方便的获得线程的一些信息

三、线程组的使用

通过现场组可以将未处理异常已经被统一处理:

  1. package cn.outofmemory.concurrent;
  2. import java.net.SocketException;
  3. public class ThreadGroupDemo2 {
  4. public static void main(String[] args) {
  5. ThreadGroup spiderGroup = new SpiderThreadGroup("spiderGroup");
  6. //可以统一设定线程是否为守护线程
  7. spiderGroup.setDaemon(true);
  8. //可以设置线程组内的最大优先级
  9. spiderGroup.setMaxPriority(Thread.NORM_PRIORITY);
  10. //初始化线程
  11. Thread spiderThread = new Thread(spiderGroup, new Runnable() {
  12. @Override
  13. public void run() {
  14. throw new RuntimeException(new SocketException());
  15. }
  16. });
  17. //启动线程
  18. spiderThread.start();
  19. }
  20. /**
  21. * 此类从ThreadGroup类继承重写了其uncaughtException方法,对于SocketException进行了特殊处理
  22. * @author outofmemory.cn
  23. *
  24. */
  25. static class SpiderThreadGroup extends ThreadGroup {
  26. public SpiderThreadGroup(String name) {
  27. super(name);
  28. }
  29. public void uncaughtException(Thread t, Throwable e) {
  30. if (e.getCause() instanceof SocketException) {
  31. System.out.println("socket exception should be process");
  32. } else {
  33. super.uncaughtException(t, e);
  34. }
  35. }
  36. }
  37. }
  38. // 运行结果:socket exception should be process

通过线程组,方便的获得应用中一共有多少个活动线程,并打印这些活动线程的名字:

  1. package cn.outofmemory.concurrent;
  2. public class ThreadDemo3 {
  3. public static void main(String[] args) {
  4. ThreadGroup g = Thread.currentThread().getThreadGroup();
  5. while (g != null) {
  6. ThreadGroup temp = g.getParent();
  7. if (temp == null) {
  8. break;
  9. }
  10. g = temp;
  11. }
  12. //现在g就是根线程组
  13. System.out.println("active count is " + g.activeCount());
  14. Thread[] all = new Thread[g.activeCount()];
  15. g.enumerate(all);
  16. for (Thread t : all) {
  17. System.out.println(t.getName());
  18. }
  19. }
  20. }
  21. /*
  22. 输出结果:(main是代码run所在的线程,其他都是虚拟机启动的线程)
  23. active count is 5
  24. Reference Handler
  25. Finalizer
  26. Signal Dispatcher
  27. Attach Listener
  28. main
  29. */

四、线程组与线程池的区别

  • 线程组是为了方便线程的管理
  • 线程池是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。

    五、补充


参考资料: java线程组(ThreadGroup)