當主線程崩潰而其它線程繼續運行時發生什么(2)
發表于:2007-07-14來源:作者:點擊數:
標簽:
診斷這種崩潰的一個輔助手段是捕捉由各種線程拋出的異常并在退出之前通知該問題的依賴線程。這正是我在清單 2 中所做的。 清單 2. 把錯誤通知給客戶機線程的示例 import java .util.Vector; public class Server2 extends Thread { Client2 client; int coun
診斷這種崩潰的一個輔助手段是捕捉由各種線程拋出的異常并在退出之前通知該問題的依賴線程。這正是我在清單 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.inter
ruptFlag = 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 擴展??赏ㄟ^ eallen@cs.rice.edu 與 Eric 聯系。
原文轉自:http://www.anti-gravitydesign.com