1. 程式人生 > >Java多執行緒(五)、多執行緒其他知識簡要介紹

Java多執行緒(五)、多執行緒其他知識簡要介紹

一、執行緒組

[java]  view plain  copy
  1. /** 
  2.  * A thread group represents a set of threads. In addition, a thread  
  3.  * group can also include other thread groups. The thread groups form 
     
  4.  * a tree in which every thread group except the initial thread group  
  5.  * has a parent.  
  6.  * <p> 
  7.  * A thread is allowed to access information about its own thread 
     
  8.  * group, but not to access information about its thread group's  
  9.  * parent thread group or any other thread groups.  
  10.  * 
  11.  * @author  unascribed
     
  12.  * @version 1.66, 03/13/08 
  13.  * @since   JDK1.0 
  14.  */  
一個執行緒組代表了一系列的執行緒。並且,一個執行緒組可以包括其他的執行緒組。除了初始執行緒組外,每個執行緒組都有一個父執行緒組,類似於樹的結構。

一個執行緒可以訪問它所線上程組的資訊, 不可以訪問它父執行緒組和其他執行緒組的資訊。

 從這段話中可以大概明白執行緒組的概念,所有的執行緒和執行緒組構成一個樹的結構,如下:



檢視Thread的API,可以看到,建立一個執行緒可以指定它的執行緒組和不指定執行緒組。如果指定其所屬的執行緒組,那麼該執行緒組是建立它的執行緒所屬執行緒組的子執行緒組。如果不指定執行緒組,則屬於預設情況,該執行緒和建立它的執行緒在同一個執行緒組。

以上面的圖舉個簡單的例子:

如果main執行緒建立了Thread1執行緒,沒有指定Thread1所在的執行緒組,那麼Thread1就預設和main執行緒屬於同一個執行緒組,即系統執行緒組。

如果main執行緒建立了Thread3執行緒,沒指定Thread3所在的執行緒組為執行緒組1,那麼執行緒組1就屬於系統執行緒組,和main執行緒在樹結構中平級。


一旦某個執行緒加入了指定執行緒組之後,該執行緒將一直屬於該執行緒組,直到該執行緒死亡,執行緒執行中途不能改變它所屬的執行緒組。因為指定執行緒所線上程組是在建立執行緒的視乎完成的,所以之後不能再修改它所在的執行緒組。

下面是ThreadGroup的方法摘要

 

方法摘要
 int activeCount()
          返回此執行緒組中活動執行緒的估計數。
 int activeGroupCount()
          返回此執行緒組中活動執行緒組的估計數。
 boolean allowThreadSuspension(boolean b)
          已過時。 此呼叫的定義取決於 suspend(),它被廢棄了。更進一步地說,此呼叫的行為從不被指定。
 void checkAccess()
          確定當前執行的執行緒是否有權修改此執行緒組。
 void destroy()
          銷燬此執行緒組及其所有子組。
 int enumerate(Thread[] list)
          把此執行緒組及其子組中的所有活動執行緒複製到指定陣列中。
 int enumerate(Thread[] list, boolean recurse)
          把此執行緒組中的所有活動執行緒複製到指定陣列中。
 int enumerate(ThreadGroup[] list)
          把對此執行緒組中的所有活動子組的引用複製到指定陣列中。
 int enumerate(ThreadGroup[] list, boolean recurse) 
          把對此執行緒組中的所有活動子組的引用複製到指定陣列中。
 int getMaxPriority()
          返回此執行緒組的最高優先順序。
 String getName()
          返回此執行緒組的名稱。
 ThreadGroup getParent()
          返回此執行緒組的父執行緒組。
 void interrupt()
          中斷此執行緒組中的所有執行緒。
 boolean isDaemon()
          測試此執行緒組是否為一個後臺程式執行緒組。
 boolean isDestroyed()
          測試此執行緒組是否已經被銷燬。
 void list()
          將有關此執行緒組的資訊列印到標準輸出。
 boolean parentOf(ThreadGroup g)
          測試此執行緒組是否為執行緒組引數或其祖先執行緒組之一。
 void resume()
          已過時。 此方法只用於聯合 Thread.suspend 和 ThreadGroup.suspend 時,因為它們所固有的容易導致死鎖的特性,所以兩者都已廢棄。有關詳細資訊,請參閱Thread.suspend()
 void setDaemon(boolean daemon)
          更改此執行緒組的後臺程式狀態。
 void setMaxPriority(int pri)
          設定執行緒組的最高優先順序。
 void stop()
          已過時。 此方法具有固有的不安全性。有關詳細資訊,請參閱 Thread.stop()
 void suspend()
          已過時。 此方法容易導致死鎖。有關詳細資訊,請參閱 Thread.suspend()
 String toString()
          返回此執行緒組的字串表示形式。
 void uncaughtException(Thread t,Throwable e) 
          當此執行緒組中的執行緒因為一個未捕獲的異常而停止,並且執行緒沒有安裝特定 Thread.UncaughtExceptionHandler 時,由 Java Virtual Machine 呼叫此方法。
 


二、執行緒組與未處理的異常

從JDK1.5開始,Java加強了執行緒的異常處理,如果執行緒執行過程中丟擲了一個未處理的異常,JVM在結束該執行緒之前會自動查詢是否有對應的Thread.UncaughtExceptionHandler物件,如果找到該處理器物件,將會呼叫該物件的uncaughtException(Thread t,Throwable e)方法來處理該異常。

Thread.UncaughtExceptionHandler是Thread類的一個內部公共靜態介面,該介面內只有一個方法:

void uncaughtException(Thread t,Throwable t),該方法中的t代表出現異常的執行緒,而e代表該執行緒丟擲的異常。

Thread類提供了兩個方法來設定異常處理器:

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)

執行緒類的所有執行緒例項設定預設的異常處理器

public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)

為指定執行緒的例項設定異常處理器

ThreadGroup類實現了Thread.UncaughtExceptionHandler介面,所以每個執行緒所屬的執行緒組將會作為預設的異常處理器。當一個執行緒丟擲未處理的異常時,JVM會首先查詢該異常對應的異常處理器(setUncaughtExceptionHandler方法設定的異常處理器),如果找到該異常處理器,將呼叫該異常處理器處理該異常,否則,JVM將會呼叫該執行緒所屬的執行緒組物件的uncaughtException方法來處理該異常,執行緒組處理異常的流程如下:

1)、如果該執行緒組有父執行緒組,則呼叫父執行緒組的uncaughtException方法來處理該異常

2)、否則,如果該執行緒例項所屬的執行緒類有預設的異常處理器(由setDefaultUncaughtExceptionHandler方法設定的異常處理器),那麼就呼叫該異常處理器來處理該異常

3)、否則,將異常除錯棧的資訊列印到System.err錯誤輸出流,並結束該執行緒。

看下面的例子:

[java]  view plain  copy
  1. class MyHandler implements Thread.UncaughtExceptionHandler{  
  2.     @Override  
  3.     public void uncaughtException(Thread t, Throwable e) {  
  4.         System.out.println("出現了異常");  
  5.         e.printStackTrace();  
  6.     }  
  7. }  
  8. public class Test{  
  9.     public static void main(String[] args) {  
  10.         Thread.currentThread().setUncaughtExceptionHandler(new MyHandler());  
  11.         int a=1/0;  
  12.     }  
  13. }  

在主執行緒中設定了異常處理器,最後捕獲了異常。



三、Callable和Future

參考:http://lavasoft.blog.51cto.com/62575/222082


四、volatile關鍵字

參考:http://lavasoft.blog.51cto.com/62575/222076


五、顯示同步鎖

參考:http://lavasoft.blog.51cto.com/62575/222084