线程组ThreadGroup标识一组线程的集合,一旦一个线程归属到一个线程组中,就不能更换其所在的线程组。
使用线程组好处:方便统一管理,线程组合一进行复制,快读定位到一个线程,统一进行一场设置等。
ThreadGroup并不属于java并发包中的内容,它是java.lang中的内容。
基本方法:
1.获取当前线程组名:
Thread.currentThread().getThreadGroup().getName();
在main方法中输出main
2.将线程放入到一个线程组中去
1ThreadGroup tg = new ThreadGroup("My Group"); 2MyThread2 thrd = new MyThread2(tg, "MyThread #1"); 3MyThread2 thrd2 = new MyThread2(tg, "MyThread #2"); 4MyThread2 thrd3 = new MyThread2(tg, "MyThread #3");
其中Thread中和ThreadGroup相关的构造函数:
1public Thread(ThreadGroup group, Runnable target) { 2 init(group, target, "Thread-" + nextThreadNum(), 0); 3} 4 5 6public Thread(ThreadGroup group, String name) { 7 init(group, null, name, 0); 8} 9 10 11public Thread(ThreadGroup group, Runnable target, String name) { 12 init(group, target, name, 0); 13} 14 15public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { 16 init(group, target, name, stackSize); 17}
它们最终都是调用同一个函数:
1 private void init(ThreadGroup g, Runnable target, String name, 2 long stackSize) { 3Thread parent = currentThread(); 4SecurityManager security = System.getSecurityManager(); 5if (g == null) { 6 //安全检查 7 if (security != null) { 8 g = security.getThreadGroup(); 9 } 10 11 //设置线程组 12 if (g == null) { 13 g = parent.getThreadGroup(); 14 } 15} 16 17 //检查可达性 18g.checkAccess(); 19 20 //是否有权限访问 21if (security != null) { 22 if (isCCLOverridden(getClass())) { 23 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 24 } 25} 26 27 //往线程组添加线程但未启动 28 g.addUnstarted(); 29 30this.group = g; 31this.daemon = parent.isDaemon();//是否守护线程 32this.priority = parent.getPriority();//优先级 33this.name = name.toCharArray(); 34if (security == null || isCCLOverridden(parent.getClass())) 35 this.contextClassLoader = parent.getContextClassLoader(); 36else 37 this.contextClassLoader = parent.contextClassLoader; 38this.inheritedAccessControlContext = AccessController.getContext(); 39this.target = target; 40setPriority(priority); 41 if (parent.inheritableThreadLocals != null) 42 this.inheritableThreadLocals = 43 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); 44 this.stackSize = stackSize; 45 tid = nextThreadID(); 46 this.me = this; 47 }
3、复制线程组:
1Thread thrds[] = new Thread[tg.activeCount()]; 2tg.enumerate(thrds);
这里的activeCount很明显就是取得活动的线程,注意。默认情况 下,连同其子线程组也会进行复制。
4、未捕获异常处理
ThreadGroup中有一个uncaughtException()方法。当线程组中某个线程发生Unchecked exception异常时,由执行环境调用此方法进行相关处理,如果有必要,可以重新定义此方法
统一异常处理:
1public class ThreadGroupExec { 2 3 public static void main(String[] args) { 4 ThreadGroup threadGroup1 = new ThreadGroup("group1"){ 5 @Override 6 public void uncaughtException(Thread t, Throwable e) { 7 System.out.println(t.getName() + ": " + e.getMessage()); 8 } 9 }; 10 11 // 这是匿名类写法 12 Thread thread1 = 13 // 这个线程是threadGroup1的一员 14 new Thread(threadGroup1, new Runnable() { 15 @Override 16 public void run() { 17 // 抛出unchecked异常 18 throw new RuntimeException("测试异常"); 19 } 20 }); 21 22 thread1.start(); 23 } 24}
查看构造函数:
1public class ThreadGroup implements Thread.UncaughtExceptionHandler { 2 private final ThreadGroup parent;//父亲ThreadGroup 3 String name;//ThreadGroupr 的名称 4 int maxPriority;//线程最大优先级 5 boolean destroyed;//是否被销毁 6 boolean daemon;//是否守护线程 7 boolean vmAllowSuspension;//是否可以中断 8 9 int nUnstartedThreads = 0;//还未启动的线程 10 int nthreads;//ThreadGroup中线程数目 11 Thread threads[];//ThreadGroup中的线程 12 13 int ngroups;//线程组数目 14 ThreadGroup groups[];//线程组数组
参考:
https://blog.csdn.net/evankaka/article/details/51627380
http://blog.csdn.net/edward\_qing\_lee/article/details/8767612