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, new MRunnable(), "線程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, new MRunnable(), "線程A");
Thread thread1 = new Thread(rootThreadGroup, new MRunnable(), "線程B");
thread0.start();
thread1.start();
ThreadGroup threadGroup1 = new ThreadGroup(rootThreadGroup, "子線程組");
Thread thread2 = new Thread(threadGroup1, new MRunnable(), "線程C");
Thread thread3 = new Thread(threadGroup1, new MRunnable(), "線程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, 所在線程組: root線程組, 父線程組: 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, new MRunnable(), "線程A");
Thread thread1 = new Thread(rootThreadGroup, new MRunnable(), "線程B");
thread0.start();
thread1.start();
ThreadGroup threadGroup1 = new ThreadGroup(rootThreadGroup, "子線程組");
Thread thread2 = new Thread(threadGroup1, new MRunnable(), "線程C");
Thread thread3 = new Thread(threadGroup1, new MRunnable(), "線程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().getName()
+ ", 父線程組: " + Thread.currentThread().getThreadGroup().getParent().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
System.out.println(Thread.currentThread().getName() + "執行結束");
}
}
復制代碼
執行結果如下:
線程名: 線程A, 所在線程組: root線程組, 父線程組: main
線程名: 線程B, 所在線程組: root線程組, 父線程組: main
線程名: 線程C, 所在線程組: 子線程組, 父線程組: root線程組
線程名: 線程D, 所在線程組: 子線程組, 父線程組: root線程組
批量中斷組內線程
線程A執行結束
線程B執行結束
線程C執行結束
線程D執行結束
復制代碼
本文只是對Java中的ThreadGroup類進行了簡單的介紹和使用示范,更多線程組的操作可以查看JDK API。
參考:
https://www.cnblogs.com/xrq730/p/4856072.html
https://www.cnblogs.com/barrywxx/p/9976417.html
最后,小編這里有一些架構資料可以分享給大家!
請加772300343領取!
謝謝關注!
