From Gossip@Openhome

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: 測試例外