當主執行緒崩潰而其它執行緒繼續執行時發生什麼(2)(轉)

BSDLite發表於2007-08-15
當主執行緒崩潰而其它執行緒繼續執行時發生什麼(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 聯絡。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617542/viewspace-958040/,如需轉載,請註明出處,否則將追究法律責任。

相關文章