熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java中的線程組

2013-11-23 19:49:49  來源: Java高級技術 

  所有線程都隸屬於一個線程組那可以是一個默認線程組亦可是一個創建線程時明確指定的組在創建之初線程被限制到一個組裡而且不能改變到一個不同的組每個應用都至少有一個線程從屬於系統線程組若創建多個線程而不指定一個組它們就會自動歸屬於系統線程組
  線程組也必須從屬於其他線程組必須在構建器裡指定新線程組從屬於哪個線程組若在創建一個線程組的時候沒有指定它的歸屬則同樣會自動成為系統線程組的一名屬下因此一個應用程序中的所有線程組最終都會將系統線程組作為自己的
  之所以要提出線程組的概念很難從字面上找到原因這多少為我們討論的主題帶來了一些混亂一般地說我們認為是由於安全或者保密方面的理由才使用線程組的根據Arnold和Gosling的說法線程組中的線程可以修改組內的其他線程包括那些位於分層結構最深處的一個線程不能修改位於自己所在組或者下屬組之外的任何線程(注釋①)然而我們很難判斷修改在這兒的具體含義是什麼下面這個例子展示了位於一個葉子組內的線程能修改它所在線程組樹的所有線程的優先級同時還能為這個內的所有線程都調用一個方法
  ①《The Java Programming Language》第該書由Arnold和Jams Gosling編著AddisonWesley於年出版
  //: TestAccessjava
  // How threads can access other threads
  // in a parent thread group
  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 TestThread(x one)
   two = new TestThread(z two);
   }
  }
  class TestThread extends Thread {
   private int i;
   TestThread(ThreadGroup g String name) {
   super(g name);
   }
   void f() {
   i++; // modify this thread
   Systemoutprintln(getName() + f());
   }
  }
  class TestThread extends TestThread {
   TestThread(ThreadGroup g String name) {
   super(g name);
   start();
   }
   public void run() {
   ThreadGroup g =
   getThreadGroup()getParent()getParent();
   glist();
   Thread[] gAll = new Thread[gactiveCount()];
   genumerate(gAll);
   for(int i = ; i < gAll.length; i++) {
   gAll[i].setPriority(Thread.MIN_PRIORITY);
   ((TestThread1)gAll[i]).f();
   }
   g.list();
   }
  } ///:~
  在main()中,我們創建了幾個ThreadGroup(線程組),每個都位於不同的“葉”上:x沒有參數,只有它的名字(一個String),所以會自動進入“system”(系統)線程組;y位於x下方,而z位於y下方。TW.WIngwiT.Com注意初始化是按照文字順序進行的,所以代碼合法。
  有兩個線程創建之後進入了不同的線程組。其中,TestThread1沒有一個run()方法,但有一個f(),用於通知線程以及打印出一些東西,以便我們知道它已被調用。而TestThread2屬於TestThread1的一個子類,它的run()非常詳盡,要做許多事情。首先,它獲得當前線程所在的線程組,然後利用getParent()在繼承樹中向上移動兩級(這樣做是有道理的,因為我想把TestThread2在分級結構中向下移動兩級)。隨後,我們調用方法activeCount(),查詢這個線程組以及所有子線程組內有多少個線程,從而創建由指向Thread的句柄構成的一個數組。enumerate()方法將指向所有這些線程的句柄置入數組gAll裡。然後在整個數組裡遍歷,為每個線程都調用f()方法,同時修改優先級。這樣一來,位於一個“葉子”線程組裡的線程就修改了位於父線程組的線程。
  調試方法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()不僅打印出ThreadGroup或者Thread的類名,也打印出了線程組的名字以及它的最高優先級。對於線程,則打印出它們的名字,並接上線程優先級以及所屬的線程組。注意list()會對線程和線程組進行縮排處理,指出它們是未縮排的線程組的“子”。
  大家可看到f()是由TestThread2的run()方法調用的,所以很明顯,組內的所有線程都是相當脆弱的。然而,我們只能訪問那些從自己的system線程組樹分支出來的線程,而且或許這就是所謂“安全”的意思。我們不能訪問其他任何人的系統線程樹。
  線程組的控制
  拋開安全問題不談,線程組最有用的一個地方就是控制:只需用單個命令即可完成對整個線程組的操作。下面這個例子演示了這一點,並對線程組內優先級的限制進行了說明。括號內的注釋數字便於大家比較輸出結果:
  //: ThreadGroup1.java
  // How thread groups control priorities
  // of the threads inside them.
  public class ThreadGroup1 {
   public static void main(String[] args) {
   // Get the system thread & print its Info:
   ThreadGroup sys =
   Thread.currentThread().getThreadGroup();
   sys.list(); // (1)
   // Reduce the system thread group priority:
   sys.setMaxPriority(Thread.MAX_PRIORITY - 1);
   // Increase the main thread priority:
   Thread curr = Thread.currentThread();
   curr.setPriority(curr.getPriority() + 1);
   sys.list(); // (2)
   // Attempt to set a new group to the max:
   ThreadGroup g1 = new ThreadGroup("g1");
   g1.setMaxPriority(Thread.MAX_PRIORITY);
   // Attempt to set a new thread to the max:
   Thread t = new Thread(g1, "A");
   t.setPriority(Thread.MAX_PRIORITY);
   g1.list(); // (3)
   // Reduce g1's max priority, then attempt
   // to increase it:
   g1.setMaxPriority(Thread.MAX_PRIORITY - 2);
   g1.setMaxPriority(Thread.MAX_PRIORITY);
   g1.list(); // (4)
   // Attempt to set a new thread to the max:
   t = new Thread(g1, "B");
   t.setPriority(Thread.MAX_PRIORITY);
   g1.list(); // (5)
   // Lower the max priority below the default
   // thread priority:
   g1.setMaxPriority(Thread.MIN_PRIORITY + 2);
   // Look at a new thread's priority before
   // and after changing it:
   t = new Thread(g1, "C");
   g1.list(); // (6)
   t.setPriority(t.getPriority() -1);
   g1.list(); // (7)
   // Make g2 a child Threadgroup of g1 and
   // try to increase its priority:
   ThreadGroup g2 = new ThreadGroup(g1, "g2");
   g2.list(); // (8)
   g2.setMaxPriority(Thread.MAX_PRIORITY);
   g2.list(); // (9)
   // Add a bunch of new threads to g2:
   for (int i = 0; i < 5; i++)
   new Thread(g2, Integer.toString(i));
   // Show information about all threadgroups
   // and threads:
   sys.list(); // (10)
   System.out.println("Starting all threads:");
   Thread[] all = new Thread[sys.activeCount()];
   sys.enumerate(all);
   for(int i = 0; i < all.length; i++)
   if(!all[i].isAlive())
   all[i].start();
   // Suspends & Stops all threads in
   // this group and its subgroups:
   System.out.println("All threads started");
   sys.suspend(); // Deprecated in Java 1.2
   // Never gets here...
   System.out.println("All threads suspended");
   sys.stop(); // Deprecated in Java 1.2
   System.out.println("All threads stopped");
   }
  } ///:~
  下面的輸出結果已進行了適當的編輯,以便用一頁能夠裝下(java.lang.已被刪去),而且添加了適當的數字,與前面程序列表中括號裡的數字對應:
  (1) ThreadGroup[name=system,maxpri=10]
   Thread[main,5,system]
  (2) ThreadGroup[name=system,maxpri=9]
   Thread[main,6,system]
  (3) ThreadGroup[name=g1,maxpri=9]
   Thread[A,9,g1]
  (4) ThreadGroup[name=g1,maxpri=
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27518.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.