淺析Java中執行緒組(ThreadGroup類)
阿新 • • 發佈:2019-12-31
一.概念
Java中使用ThreadGroup類來代表執行緒組,表示一組執行緒的集合,可以對一批執行緒和執行緒組進行管理。可以把執行緒歸屬到某一個執行緒組中,執行緒組中可以有執行緒物件,也可以有執行緒組,組中還可以有執行緒,這樣的組織結構有點類似於樹的形式,如圖所示。
使用者建立的所有執行緒都屬於指定執行緒組,如果沒有顯式指定屬於哪個執行緒組,那麼該執行緒就屬於預設執行緒組(即main執行緒組)。預設情況下,子執行緒和父執行緒處於同一個執行緒組。
此外,只有在建立執行緒時才能指定其所在的執行緒組,執行緒執行中途不能改變它所屬的執行緒組,也就是說執行緒一旦指定所在的執行緒組就不能改變。
二.為什麼要使用執行緒組
1.安全
同一個執行緒組的執行緒是可以相互修改對方的資料的。但如果在不同的執行緒組中,那麼就不能“跨執行緒組”修改資料,可以從一定程度上保證資料安全。
2.批量管理
可以批量管理執行緒或執行緒組物件,有效地對執行緒或執行緒組物件進行組織或控制。
三.執行緒組使用示例
1.執行緒關聯執行緒組:一級關聯
所謂一級關聯就是父物件中有子物件,但並不建立孫物件。比如建立一個執行緒組,然後將建立的執行緒歸屬到該組中,從而對這些執行緒進行有效的管理。程式碼示例如下:
public class ThreadGroupTest {
public static void main(String[] args) {
ThreadGroup rootThreadGroup = new ThreadGroup("root執行緒組");
Thread thread0 = new Thread(rootThreadGroup,new MRunnable(),"執行緒A");
Thread thread1 = new Thread(rootThreadGroup,"執行緒B");
thread0.start();
thread1.start();
}
}
class MRunnable implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("執行緒名: " + Thread.currentThread().getName()
+ ",所線上程組: " + Thread.currentThread().getThreadGroup().getName()) ;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
複製程式碼
執行結果如下:
執行緒名: 執行緒A,所線上程組: root執行緒組
執行緒名: 執行緒B,所線上程組: root執行緒組
複製程式碼
2.執行緒關聯執行緒組:多級關聯
所謂的多級關聯就是父物件中有子物件,子物件中再建立孫物件也就出現了子孫的效果了。比如使用下圖第二個構造方法,將子執行緒組歸屬到某個執行緒組,再將建立的執行緒歸屬到子執行緒組,這樣就會有執行緒樹的效果了。
程式碼示例如下:public class ThreadGroupTest {
public static void main(String[] args) {
ThreadGroup rootThreadGroup = new ThreadGroup("root執行緒組");
Thread thread0 = new Thread(rootThreadGroup,"執行緒B");
thread0.start();
thread1.start();
ThreadGroup threadGroup1 = new ThreadGroup(rootThreadGroup,"子執行緒組");
Thread thread2 = new Thread(threadGroup1,"執行緒C");
Thread thread3 = new Thread(threadGroup1,"執行緒D");
thread2.start();
thread3.start();
}
}
class MRunnable implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("執行緒名: " + Thread.currentThread().getName()
+ ",所線上程組: " + Thread.currentThread().getThreadGroup().getName()
+ ",父執行緒組: " + Thread.currentThread().getThreadGroup().getParent().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
複製程式碼
執行結果如下:
執行緒名: 執行緒A,所線上程組: root執行緒組,父執行緒組: main
執行緒名: 執行緒B,父執行緒組: main
執行緒名: 執行緒C,所線上程組: 子執行緒組,父執行緒組: root執行緒組
執行緒名: 執行緒D,父執行緒組: root執行緒組
複製程式碼
3.批量管理組內執行緒
使用執行緒組自然是要對執行緒進行批量管理,比如可以批量中斷組內執行緒,程式碼示例如下:
public class ThreadGroupTest {
public static void main(String[] args) {
ThreadGroup rootThreadGroup = new ThreadGroup("root執行緒組");
Thread thread0 = new Thread(rootThreadGroup,"執行緒D");
thread2.start();
thread3.start();
rootThreadGroup.interrupt();
System.out.println("批量中斷組內執行緒");
}
}
class MRunnable implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("執行緒名: " + Thread.currentThread().getName()
+ ",父執行緒組: " + Thread.currentThread().getThreadGroup().getParent().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
System.out.println(Thread.currentThread().getName() + "執行結束");
}
}
複製程式碼
執行結果如下:
執行緒名: 執行緒A,父執行緒組: root執行緒組
批量中斷組內執行緒
執行緒A執行結束
執行緒B執行結束
執行緒C執行結束
執行緒D執行結束
複製程式碼
本文只是對Java中的ThreadGroup類進行了簡單的介紹和使用示範,更多執行緒組的操作可以檢視JDK API。
參考: