1. 程式人生 > 程式設計 >淺析Java中執行緒組(ThreadGroup類)

淺析Java中執行緒組(ThreadGroup類)

一.概念

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。

參考:

Java多執行緒16:執行緒組

Java執行緒組(ThreadGroup)使用