ITEEDU

Java Gossip: ThreadGroup

在Java中每个执行绪都属于某个「执行绪群组」(ThreadGroup)管理的一员,例如若您是在main ()主工作流程中产生一个执行绪,则产生的执行绪属于main这个执行绪群组管理的一员,您可以使用下面的指令来取得目前执行绪所属的执行绪群组名称::

Thread.currentThread().getThreadGroup().getName();

每一个执行绪产生时,都会被归入某个执行绪群组,这视您的执行绪是在哪个群组中产生,如果没有指定,则归入产生该子执行绪的执行绪群组中,您也可以自行指定执行绪群组,执行绪一但归入某个群组,就无法更换群组。

ThreadGroup正如其名,可以统一管理整个群组中的执行绪,您可以使用以下的方式来产生群组,并在产生执行绪的时候,一并指定其群组:

ThreadGroup threadGroup1 = new ThreadGroup("group1");
ThreadGroup threadGroup2 = new ThreadGroup("group2");

Thread thread1 = new Thread(threadGroup1, "group1's member");
Thread thread2 = new Thread(threadGroup2, "group2's member"); 

ThreadGroup中的某些方法,可以对所有的执行绪产生作用,例如interrupt()可以interrupt群组中所有的执行绪, setMaxPriority()可以设定群组中执行绪所能拥有的最大优先权(本来就拥有更高优先权的执行绪不受影响),这方面您可以查询在线API文件 来了解有哪些方法可以使用。

如果我们想要一次取得群组中所有的执行绪进行操作,您可以使用enumerate()方法,例如:

Thread[] threads = new Thread[threadGroup1.activeCount()];
threadGroup1.enumerate(threads);

activeCount()方法取得群组中作用中的执行绪数量,enumerate()方法要传入一个Thread数组对象,它会将执行绪对象设定至每个数组字段中,之后您就可以指定数组索引来操作这些执行绪。

ThreadGroup中有个uncaughtException()方法,这是当群组中某个执行绪发生unchecked例外时,由执行环境呼叫此方法进行处理,如果有必要,您可以重新定义此方法,一个例子如下:

ThreadGroupDemo.java
package onlyfun.caterpillar;
import java.io.*;
public class ThreadGroupDemo {
	public static void main(String[] args) {
		ThreadGroup threadGroup1 =
		// 这是匿名类别写法
		new ThreadGroup("group1") {
			// 继承ThreadGroup并重新定义以下方法
			// 在执行绪成员丢出unchecked exception
			// 会执行此方法
			public void uncaughtException(Thread t, Throwable e) {
				System.out.println(t.getName() + ": "
				+ e.getMessage());
			}
		};
		// 这是匿名类别写法
		Thread thread1 =
		// 这个执行绪是threadGroup1的一员
		new Thread(threadGroup1,
		new Runnable() {
			public void run() {
				// 丢出unchecked例外
				throw new RuntimeException("测试例外");
			}
		});
		thread1.start();
	}
}

在uncaughtException()方法的参数中,第一个参数可以取得发生例外的执行绪实例,而第二个参数可以取得例外对象,范例中显示了执行绪的名称及例外讯息,结果如下所示:

Thread-0:  测试例外