當主執行緒崩潰而其它執行緒繼續執行時發生什麼(2)(轉)
當主執行緒崩潰而其它執行緒繼續執行時發生什麼(2)(轉)[@more@]診斷這種崩潰的一個輔助手段是捕捉由各種執行緒丟擲的異常並在退出之前通知該問題的依賴執行緒。這正是我在清單 2 中所做的。
清單 2. 把錯誤通知給客戶機執行緒的示例
import java.util.Vector;
public class Server2 extends Thread {
Client2 client;
int counter;
public Server2(Client2 _client) {
this.client = _client;
this.counter = 0;
}
public void run() {
try {
while (counter < 10) {
this.client.queue.addElement(new Integer(counter));
counter++;
}
throw new RuntimeException("counter >= 10");
}
catch (Exception e) {
this.client.interruptFlag = true;
throw new RuntimeException(e.toString());
}
}
public static void main(String[] args) {
Client2 c = new Client2();
Server2 s = new Server2(c);
c.start();
s.start();
}
}
class Client2 extends Thread {
Vector queue;
boolean interruptFlag;
public Client2() {
this.queue = new Vector();
this.interruptFlag = false;
}
public void run() {
while (! interruptFlag) {
if (! (queue.size() == 0)) {
processNextElement();
}
}
// Processes whatever elements remain on the queue before exiting.
while (! (queue.size() == 0)) {
processNextElement();
}
System.out.flush();
}
private void processNextElement() {
Object next = queue.elementAt(0);
queue.removeElementAt(0);
System.out.println(next);
}
}
處理被丟擲的異常的其它選項可能是呼叫 System.exit。這個選項在程式的主執行緒發生崩潰而其它執行緒不管理任何臨界資源的時候是有意義的。然而在其它情況下,這可能是危險的。例如,考慮這樣一個示例,其它執行緒中的一個正在管理一個開啟的檔案。如果這是實際的情況,那麼只是退出程式會導致資源洩漏。
即使在上面的簡單示例中,在 server 執行緒中呼叫 System.exit 也會導致 client 未處理其佇列上的任何剩餘元素就退出。
事實上,就是這樣的問題促使 Sun 不建議執行緒的 stop 方法。由於強行停止一個執行緒會使資源陷入非一致狀態,所以 stop 方法破壞了語言的安全性模型。
想了解 Sun 的更多不建議理由,請參閱參考資料。
總結
這裡是本週錯誤模式的總結:
模式:孤執行緒
症狀:一個鎖定多執行緒程式,它具有或不具有將堆疊跟蹤列印到標準錯誤。
致因:多個程式執行緒一直等待來自某個執行緒的輸入,而該執行緒在丟擲一個未被捕捉的異常後就退出了。
治療和預防措施:把異常處理程式碼放到主執行緒中以在崩潰來臨之際通知依賴執行緒。
參考資料
參加本文的討論論壇。
閱讀關於為什麼不建議 Thread.stop 的 Sun 的解釋。
Neel V. Kumar 在他的文章“Java 程式中的多執行緒”(developerWorks,2000 年 3 月)中提供除錯多執行緒 Java 的途徑。
Peter Haggar 的“最佳化 Java 程式設計中的併發”(IBM PartnerWorld for Developers)是一份優秀的白皮書,它討論透過執行多執行緒來併發存取資料會導致的常見問題。
想獲得編寫多執行緒 Java 程式的介紹,請參閱 Alex Roetter 的文章“編寫多執行緒 Java 應用程式”(developerWorks,2001 年 2 月)。
想為您的 Java 應用程式中的多執行緒問題獲得技術幫助,請訪問多執行緒 Java 程式設計討論論壇。
Brian Goetz 在他共三部分的系列輕鬆使用執行緒中處理困難的執行緒問題。
JUnit 主頁提供討論程式測試方法的很多有趣文章的連結,並提供 JUnit 的最新版本。
利用 Java 除錯教程(developerWorks,2001 年 2 月),獲取通用除錯技術的幫助。
閱讀 Eric 所有診斷 Java 程式碼的文章,其中多數著重討論錯誤模式。
請在 developerWorks Java 技術專區查詢更多的 Java 參考資料。
關於作者
Eric Allen 從 Cornell 大學獲得電腦科學及數學的學士學位,並且是 Rice 大學 Java 程式語言小組的博士候選人。在回 Rice 專心攻讀學位前,Eric 是 Cycorp,Inc. 的 Java 開發者帶頭人。他還在 JavaWorld 上主持 Java 初學者討論論壇。他的研究包括在源程式和位元組碼級別上 Java 語言的語義模型和靜態分析工具開發。Eric 還幫助開發 Rice 的 NextGen 程式語言編譯器,NextGen 是一個支援泛執行時型別的 Java 擴充套件。可透過 與 Eric 聯絡。
清單 2. 把錯誤通知給客戶機執行緒的示例
import java.util.Vector;
public class Server2 extends Thread {
Client2 client;
int counter;
public Server2(Client2 _client) {
this.client = _client;
this.counter = 0;
}
public void run() {
try {
while (counter < 10) {
this.client.queue.addElement(new Integer(counter));
counter++;
}
throw new RuntimeException("counter >= 10");
}
catch (Exception e) {
this.client.interruptFlag = true;
throw new RuntimeException(e.toString());
}
}
public static void main(String[] args) {
Client2 c = new Client2();
Server2 s = new Server2(c);
c.start();
s.start();
}
}
class Client2 extends Thread {
Vector queue;
boolean interruptFlag;
public Client2() {
this.queue = new Vector();
this.interruptFlag = false;
}
public void run() {
while (! interruptFlag) {
if (! (queue.size() == 0)) {
processNextElement();
}
}
// Processes whatever elements remain on the queue before exiting.
while (! (queue.size() == 0)) {
processNextElement();
}
System.out.flush();
}
private void processNextElement() {
Object next = queue.elementAt(0);
queue.removeElementAt(0);
System.out.println(next);
}
}
處理被丟擲的異常的其它選項可能是呼叫 System.exit。這個選項在程式的主執行緒發生崩潰而其它執行緒不管理任何臨界資源的時候是有意義的。然而在其它情況下,這可能是危險的。例如,考慮這樣一個示例,其它執行緒中的一個正在管理一個開啟的檔案。如果這是實際的情況,那麼只是退出程式會導致資源洩漏。
即使在上面的簡單示例中,在 server 執行緒中呼叫 System.exit 也會導致 client 未處理其佇列上的任何剩餘元素就退出。
事實上,就是這樣的問題促使 Sun 不建議執行緒的 stop 方法。由於強行停止一個執行緒會使資源陷入非一致狀態,所以 stop 方法破壞了語言的安全性模型。
想了解 Sun 的更多不建議理由,請參閱參考資料。
總結
這裡是本週錯誤模式的總結:
模式:孤執行緒
症狀:一個鎖定多執行緒程式,它具有或不具有將堆疊跟蹤列印到標準錯誤。
致因:多個程式執行緒一直等待來自某個執行緒的輸入,而該執行緒在丟擲一個未被捕捉的異常後就退出了。
治療和預防措施:把異常處理程式碼放到主執行緒中以在崩潰來臨之際通知依賴執行緒。
參考資料
參加本文的討論論壇。
閱讀關於為什麼不建議 Thread.stop 的 Sun 的解釋。
Neel V. Kumar 在他的文章“Java 程式中的多執行緒”(developerWorks,2000 年 3 月)中提供除錯多執行緒 Java 的途徑。
Peter Haggar 的“最佳化 Java 程式設計中的併發”(IBM PartnerWorld for Developers)是一份優秀的白皮書,它討論透過執行多執行緒來併發存取資料會導致的常見問題。
想獲得編寫多執行緒 Java 程式的介紹,請參閱 Alex Roetter 的文章“編寫多執行緒 Java 應用程式”(developerWorks,2001 年 2 月)。
想為您的 Java 應用程式中的多執行緒問題獲得技術幫助,請訪問多執行緒 Java 程式設計討論論壇。
Brian Goetz 在他共三部分的系列輕鬆使用執行緒中處理困難的執行緒問題。
JUnit 主頁提供討論程式測試方法的很多有趣文章的連結,並提供 JUnit 的最新版本。
利用 Java 除錯教程(developerWorks,2001 年 2 月),獲取通用除錯技術的幫助。
閱讀 Eric 所有診斷 Java 程式碼的文章,其中多數著重討論錯誤模式。
請在 developerWorks Java 技術專區查詢更多的 Java 參考資料。
關於作者
Eric Allen 從 Cornell 大學獲得電腦科學及數學的學士學位,並且是 Rice 大學 Java 程式語言小組的博士候選人。在回 Rice 專心攻讀學位前,Eric 是 Cycorp,Inc. 的 Java 開發者帶頭人。他還在 JavaWorld 上主持 Java 初學者討論論壇。他的研究包括在源程式和位元組碼級別上 Java 語言的語義模型和靜態分析工具開發。Eric 還幫助開發 Rice 的 NextGen 程式語言編譯器,NextGen 是一個支援泛執行時型別的 Java 擴充套件。可透過 與 Eric 聯絡。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-958040/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java執行緒池核心執行緒用盡後為何優先排隊而不是繼續建立執行緒直至最大執行緒數?Java執行緒
- 執行緒崩潰為什麼不會導致 JVM 崩潰執行緒JVM
- 保證執行緒在主執行緒執行執行緒
- 主執行緒等待所有其他執行緒執行完畢,然後再繼續執行主執行緒的邏輯,有以下幾種方法可以實現:執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- Thread 中的 join() 方法的作用是呼叫執行緒等待該執行緒執行完後,再繼續執行thread執行緒
- 什麼是Python執行緒?Python執行緒如何建立?Python執行緒
- QT 主執行緒子執行緒互相傳值QT執行緒
- 玩轉java多執行緒 之多執行緒基礎 執行緒狀態 及執行緒停止實戰Java執行緒
- 【多執行緒與高併發】Java守護執行緒是什麼?什麼是Java的守護執行緒?執行緒Java
- 執行緒(2)執行緒
- redis為什麼用單執行緒不用多執行緒Redis執行緒
- 執行緒池管理(1)-為什麼需要執行緒池執行緒
- 什麼是執行緒安全和執行緒不安全執行緒
- 執行緒與多執行緒執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒和執行緒池執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒 執行緒池 Task執行緒
- 什麼?一個核同時執行兩個執行緒?執行緒
- 多執行緒(2)-執行緒同步互斥鎖Mutex執行緒Mutex
- Java多執行緒學習(2)執行緒控制Java執行緒
- 什麼是多執行緒?Python多執行緒有什麼優勢?執行緒Python
- Java 併發:執行緒、執行緒池和執行器全面教程Java執行緒
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- Java多執行緒-執行緒中止Java執行緒
- 多執行緒之初識執行緒執行緒
- 執行緒控制之休眠執行緒執行緒
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- 模擬主執行緒等待子執行緒的過程執行緒
- python基礎執行緒-管理併發執行緒Python執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- 案例解析:執行緒池使用不當導致的系統崩潰執行緒
- 執行緒、開啟執行緒的兩種方式、執行緒下的Join方法、守護執行緒執行緒
- 執行緒(一)——執行緒,執行緒池,Task概念+程式碼實踐執行緒
- java執行緒之守護執行緒和使用者執行緒Java執行緒
- 當執行時,發生了什麼?