您不能簡單地停止服務器。清理過程可能需要一段時間,因爲您需要確保一致性。
想象一下數據庫服務器,如果您在執行事務時將其關閉,則可能會使其數據不一致。這就是爲什麼它通常需要一段時間才能關閉服務器。
- 您必須先停止接受服務器中的新連接 。
- 然後您可以等待 當前工作線程完成 他們的工作,然後關閉 服務器並正式關閉。
- 或者你強制工作線程 關閉與
客戶他們的連接(可能使用某種標誌的
的建議)。這可能是 意味着一些清理,以保持數據 一致,例如恢復 傳輸或您在文件或內存中完成的任何類型的更改 。
根據我的理解,關閉與服務器端客戶端的連接應該會導致客戶端獲得EOF。
[編輯-1]
我已經深入研究在這個問題上有點,只是因爲我沒有在使用了一段時間插座,因爲我發現這個問題有意思。我認爲,由於它已被其他人指出,唯一的選擇是關閉插座,根據Javadocs將自動關閉輸入和輸出流/
如果有線程未被IO阻塞的機會,但處於等待狀態或休眠狀態,我認爲仍然建議爲給定套接字的相應工作線程發出Thread.interrupt();因爲不能確定每個線程的狀態是否被阻塞。
public static class IOServerWorker implements Runnable{
private Socket socket;
public IOServerWorker(Socket socket){
this.socket = socket;
}
@Override
public void run() {
String line = null;
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((line = reader.readLine())!=null){
System.out.println(line);
}
reader.close();
}catch(IOException e){
//TODO: do cleanup here
//TODO: log | wrap | rethrow exception
}
}
}
當I/O中的工作者被阻塞時,我無法檢查這個標誌 – 2011-04-11 17:24:39
最佳做法是使用Thread.interrupted()。這是標準的解決方案,可以在ThreadPool中正常工作。 – 2011-04-11 19:04:45
@Andrey Vityuk Thread.interrupted實際上不是很好的做法,因爲它重置了中斷標誌。你可能意味着Thread.interrupt或Thread.isInterrupted。這就是說,正如我在我的回答中所說的,許多IO構造不考慮線程中斷,因此(儘管我部分同意你的評論)它不適用於這種情況。 – 2011-04-12 00:30:53