執行緒組介紹
執行緒組(ThreadGroup
)簡單來說就是一個執行緒集合。執行緒組的出現是為了更方便地管理執行緒。
執行緒組是父子結構的,一個執行緒組可以整合其他執行緒組,同時也可以擁有其他子執行緒組。從結構上看,執行緒組是一個樹形結構,每個執行緒都隸屬於一個執行緒組,執行緒組又有父執行緒組,這樣追溯下去,可以追溯到一個根執行緒組——System執行緒組。
下面介紹一下執行緒組樹的結構:
- JVM建立的system執行緒組是用來處理JVM的系統任務的執行緒組,例如物件的銷燬等。
- system執行緒組的直接子執行緒組是main執行緒組,這個執行緒組至少包含一個main執行緒,用於執行main方法。
- main執行緒組的子執行緒組就是應用程式建立的執行緒組。
你可以在main方法中看到JVM建立的system執行緒組和main執行緒組:
public static void main(String[] args) {
ThreadGroup mainThreadGroup=Thread.currentThread().getThreadGroup();
ThreadGroup systenThreadGroup=mainThreadGroup.getParent();
System.out.println("systenThreadGroup name = "+systenThreadGroup.getName());
System.out.println("mainThreadGroup name = "+mainThreadGroup.getName());
}
複製程式碼
console輸出:
systenThreadGroup name = system
mainThreadGroup name = main
複製程式碼
一個執行緒可以訪問其所屬執行緒組的資訊,但不能訪問其所屬執行緒組的父執行緒組或者其他執行緒組的資訊。
執行緒組的構造
java.lang.ThreadGroup
提供了兩個建構函式:
Constructor | Description |
---|---|
ThreadGroup(String name) | 根據執行緒組名稱建立執行緒組,其父執行緒組為main執行緒組 |
ThreadGroup(ThreadGroup parent, String name) | 根據執行緒組名稱建立執行緒組,其父執行緒組為指定的parent執行緒組 |
下面演示一下這兩個建構函式的用法:
public static void main(String[] args) {
ThreadGroup subThreadGroup1 = new ThreadGroup("subThreadGroup1");
ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "subThreadGroup2");
System.out.println("subThreadGroup1 parent name = " + subThreadGroup1.getParent().getName());
System.out.println("subThreadGroup2 parent name = " + subThreadGroup2.getParent().getName());
}
複製程式碼
console輸出:
subThreadGroup1 parent name = main
subThreadGroup2 parent name = subThreadGroup1
複製程式碼
ThreadGroup方法介紹
ThreadGroup提供了很多有用的方法,下面提供了這些方法的簡要介紹,以及部分方法的使用示例。
S.N. | Method | Description |
---|---|---|
1) | void checkAccess() | This method determines if the currently running thread has permission to modify the thread group. |
2) | int activeCount() | This method returns an estimate of the number of active threads in the thread group and its subgroups. |
3) | int activeGroupCount() | This method returns an estimate of the number of active groups in the thread group and its subgroups. |
4) | void destroy() | This method destroys the thread group and all of its subgroups. |
5) | int enumerate(Thread[] list) | This method copies into the specified array every active thread in the thread group and its subgroups. |
6) | int getMaxPriority() | This method returns the maximum priority of the thread group. |
7) | String getName() | This method returns the name of the thread group. |
8) | ThreadGroup getParent() | This method returns the parent of the thread group. |
9) | void interrupt() | This method interrupts all threads in the thread group. |
10) | boolean isDaemon() | This method tests if the thread group is a daemon thread group. |
11) | void setDaemon(boolean daemon) | This method changes the daemon status of the thread group. |
12) | boolean isDestroyed() | This method tests if this thread group has been destroyed. |
13) | void list() | This method prints information about the thread group to the standard output. |
14) | boolean parentOf(ThreadGroup g) | This method tests if the thread group is either the thread group argument or one of its ancestor thread groups. |
15) | void suspend() | This method is used to suspend all threads in the thread group. |
16) | void resume() | This method is used to resume all threads in the thread group which was suspended using suspend() method. |
17) | void setMaxPriority(int pri) | This method sets the maximum priority of the group. |
18) | void stop() | This method is used to stop all threads in the thread group. |
19) | String toString() | This method returns a string representation of the Thread group. |
檢視執行緒組資訊
下面演示了檢視當前執行緒組的資訊。
public static void list(){
ThreadGroup tg = new ThreadGroup ("subgroup 1");
Thread t1 = new Thread (tg, "thread 1");
Thread t2 = new Thread (tg, "thread 2");
Thread t3 = new Thread (tg, "thread 3");
tg = new ThreadGroup ("subgroup 2");
Thread t4 = new Thread (tg, "my thread");
tg = Thread.currentThread ().getThreadGroup ();
int agc = tg.activeGroupCount ();
System.out.println ("Active thread groups in " + tg.getName () + " thread group: " + agc);
tg.list ();
}
複製程式碼
輸出如下:
Active thread groups in main thread group: 2
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
java.lang.ThreadGroup[name=subgroup 1,maxpri=10]
java.lang.ThreadGroup[name=subgroup 2,maxpri=10]
複製程式碼
終止執行緒組中的所有執行緒
一個執行緒應由其他執行緒來強制中斷或停止,而是應該由執行緒自己自行停止。
因此 Thread.currentThread().stop()
, Thread.currentThread().suspend()
, Thread.currentThread().resume()
都已經被廢棄了。
interrupt()
方法的作用是通知執行緒應該中斷了,具體到底中斷還是繼續執行,由被通知的執行緒處理。
public class ThreadGroupExampleInterrupt {
public static void main(String[] args) {
// Start two threads
MyThread mt = new MyThread();
mt.setName("A");
mt.start();
mt = new MyThread();
mt.setName("B");
mt.start();
// Wait 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Interrupt all methods in the same thread group as the main thread
Thread.currentThread().getThreadGroup().interrupt();
}
//一個啟動以後進入等待,直到被interrupt的執行緒
static class MyThread extends Thread {
public void run() {
synchronized ("A") {
System.out.println(getName() + " about to wait.");
try {
"A".wait();
} catch (InterruptedException e) {
System.out.println(getName() + " interrupted.");
}
System.out.println(getName() + " terminating.");
}
}
}
}
複製程式碼
執行main
方法輸出:
A about to wait.
B about to wait.
A interrupted.
A terminating.
B interrupted.
B terminating.
複製程式碼
總結
本節介紹了執行緒組(ThreadGroup
)的概念,及其結構和建構函式,並演示了使用執行緒組方便地管理組內執行緒的幾個方法。
本節是併發系列教程的一節,更多相關教程可以訪問文章後面的連結。
後續會有更多關於併發程式設計的知識點的介紹,並且會結合企業專案進行實戰介紹,歡迎繼續關注。