2011-04-23 147 views
0

我目前正在嘗試編寫一個Logger風格的線程。我沒有使用現有的API,因爲這部分是爲了改進我的線程。Java線程沒有清理

當線程中斷時,我需要它正常關閉,刷新最後一個排隊的消息並關閉文件流。

目前,它關閉,但消息通常仍在排隊,我擔心文件流沒有正常關閉。

這是我的run()

while(!shutdown){ 
    writeMessages(); 
    try{ 
     Thread.sleep(5000); 
    } 
    catch (InterruptedException e) { 
    } 
}try { 
    writeMessages(); 
} catch (CustomException e1) { 
    e1.printStackTrace(); 
} 
try { 
    logFile.close(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
try { 
    errFile.close(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
+0

確定這些消息在您調用writeMessages之後不會被添加* – Erik 2011-04-23 23:32:23

+0

是的。我相當肯定這個問題缺乏對線程清理的理解 – InfernalRapture 2011-04-23 23:36:22

+0

您發佈的代碼段沒有這樣的問題 - 錯誤在別處 – Erik 2011-04-23 23:38:38

回答

2

Java有非常乾淨的方式來關閉線程。它被稱爲中斷標誌。當你想中斷線程您只需編寫下面的代碼:

thread.interrupt(); 
thread.join(); 

而在後臺線程的Runnable你應該檢查中斷標誌位和相應的行爲。如果你想線程生存,直到消息被留下,你可以做到這一點在下面的方式(我假設你有檢查的一些方法是否還有任何消息,對我來說,這是一個BlockingQueue):

Thread self = Thread.currentThread(); 
BlockingQueue<String> messages = ...; 

while (!self.isInterrupted() || !messages.isEmpty()) { 
    try { 
    String message = messages.take(); 
    writeMessage(message); 
    } catch (InterruptedException) { 
    self.interrupt(); 
    } 
} 

還有一事情。在請求線程關閉後,應確保消息不會添加到隊列中在寫入線程之前關閉所有線程生成消息。這也可以做檢查線程中斷標誌(你需要知道引用一個作家線程):

public void addMessage(String message) { 
    if (thread.isInterrupted() || !thread.isAlive()) { 
    throw new IllegalStateException(); 
    } 
    messages.add(message); 
} 

此外,我建議你看在java.util.concurrent包。它爲多線程應用程序提供了很多有用的工具。

0

所有其他評論都很好,我只是想補充 - 確保在關閉它們之前在輸出流上調用flush()。