標籤:安全 對象 流程 tools virtual resume rup 安裝 ota
一、線程組
[java] view plain copy
- /**
- * A thread group represents a set of threads. In addition, a thread
- * group can also include other thread groups. The thread groups form
- * a tree in which every thread group except the initial thread group
- * has a parent.
- * <p>
- * A thread is allowed to access information about its own thread
- * group, but not to access information about its thread group‘s
- * parent thread group or any other thread groups.
- *
- * @author unascribed
- * @version 1.66, 03/13/08
- * @since JDK1.0
- */
一個線程組代表了一系列的線程。並且,一個線程組可以包括其他的線程組。除了初始線程組外,每個線程組都有一個父線程組,類似於樹的結構。
一個線程可以訪問它所線上程組的資訊, 不可以訪問它父線程組和其他線程組的資訊。
從這段話中可以大概明白線程組的概念,所有的線程和線程組構成一個樹的結構,如下:
查看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
- class MyHandler implements Thread.UncaughtExceptionHandler{
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- System.out.println("出現了異常");
- e.printStackTrace();
- }
- }
- public class Test{
- public static void main(String[] args) {
- Thread.currentThread().setUncaughtExceptionHandler(new MyHandler());
- int a=1/0;
- }
- }
在主線程中設定了異常處理器,最後捕獲了異常。
三、Callable和Future
參考:http://lavasoft.blog.51cto.com/62575/222082
四、volatile關鍵字
參考:http://lavasoft.blog.51cto.com/62575/222076
五、顯示同步鎖
參考:http://lavasoft.blog.51cto.com/62575/222084
Java多線程 5 多線程其他知識簡要介紹