首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 執行緒組完整解析:存取控制、優先級管理與批量操作

     編輯:Java 相關知識

基本概念

所有執行緒隸屬一個執行緒組(預設或建立時指定)。建立之初即限制在組內,**無法改變到不同組**。每個應用至少有一個執行緒屬於系統執行緒組。若建立多執行緒不指定組,自動歸屬系統組。

執行緒組也必須隸屬其他組,建構子必須指定父組。若未指定,同樣自動成為系統組屬下。因此應用中所有執行緒組最終以系統組為「父」。

為何需要執行緒組?安全性考量

字面難尋原因,帶來些混亂。一般認為因「安全」或「保密」理由。據 Arnold 和 Gosling:《執行緒組中的執行緒可修改組內其他執行緒(含分層最深處)。執行緒無法修改自己所在組或下屬組之外的任何執行緒》。但「修改」具體含義難判斷。

實例:葉子組執行緒可修改整棵樹

//: TestAccess.java
public class TestAccess {
    public static void main(String[] args) {
        ThreadGroup x = new ThreadGroup("x"),
                    y = new ThreadGroup(x, "y"),
                    z = new ThreadGroup(y, "z");
        Thread one = new TestThread1(x, "one"),
               two = new TestThread2(z, "two");
    }
}

class TestThread1 extends Thread {
    private int i;
    TestThread1(ThreadGroup g, String name) { super(g, name); }
    void f() { i++; System.out.println(getName() + " f()"); }
}

class TestThread2 extends TestThread1 {
    TestThread2(ThreadGroup g, String name) { super(g, name); start(); }
    public void run() {
        ThreadGroup g = getThreadGroup().getParent().getParent(); // 向上兩層到 x
        g.list();
        Thread[] gAll = new Thread[g.activeCount()];
        g.enumerate(gAll);
        for(int i = 0; i < gAll.length; i++) {
            gAll[i].setPriority(Thread.MIN_PRIORITY);
            ((TestThread1)gAll[i]).f();
        }
        g.list();
    }
} ///:~

輸出結果分析

java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,5,x]
java.lang.ThreadGroup[name=y,maxpri=10]
java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,5,z]
one f()
two f()
java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,1,x]
java.lang.ThreadGroup[name=y,maxpri=10]
java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,1,z]
  • list() 列印執行緒組/執行緒類名、名稱、最高優先級、所屬組
  • 縮排顯示父子關係
  • 葉子組 z 的執行緒 two 修改了父組 x 的執行緒 one 優先級並呼叫其方法
  • 只能存取自己系統組樹分支出來的執行緒——這或許就是所謂「安全」

執行緒組的控制功能:批量操作

拋開安全問題,**控制是最實用之處**:單個命令完成整組操作。下例演示優先級限制機制:

ThreadGroup1.java 關鍵實驗與輸出

  1. 系統組初始 maxpri=10,main 執行緒優先級 5
  2. 降低系統組最高優先級到 9,main 提升到 6
  3. 建立子組 g1,嘗試設最高優先級 10 → **失敗,限制為 9**(不可超過父組)
  4. 降低 g1 到 8,嘗試升回 10 → **失敗**(只能降不能升)
  5. 新建執行緒 B,設最高優先級 → 受限於 8
  6. 降低 g1 到 3(低於預設 6),新建執行緒 C → **仍用預設 6 建立**(組最高優先級不影響預設優先級)
  7. 嘗試降低 C 優先級 → 受限於 3(只在嘗試改變時強制遵守)
  8. 建立子組 g2 隸屬 g1,嘗試提高優先級 → **失敗,限制為 3**(子組不可超過父組)

鐵律: 子組最高優先級在任何時候只能 ≤ 父組最高優先級。

批量操作方法

  • 遍歷整個執行緒樹啟動未啟動執行緒
  • sys.suspend() 掛起系統組 → 同時掛起 main 執行緒 → 程式關閉(suspend()/stop() 在 Java 1.2 已棄用)
  • ThreadGroup 繼承 Object 擁有 wait(),可在同步區塊取得物件鎖後調用 wait(毫秒) 暫停任意秒數
  • suspend()/resume() 可中止/啟動整組及子組(同樣棄用)

表面看執行緒組讓人摸不著頭腦,**但實務上很少直接使用**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved