假設你希望能夠對付「行」,我可能會像這樣的東西開始:
public class SocketReader implements Runnable {
private final InputStream stream;
private final Queue<String> destination;
private volatile boolean active = true;
private SocketReader(InputStream stream, Queue<String> destination) {
this.stream = stream;
this.destination = destination;
}
public static SocketReader getReader(Socket toRead, Queue<String> destination) throws IOException {
return new SocketReader(toRead.getInputStream(), destination);
}
public void shutdown() {
active = false;
}
public void run() {
while(active) {
if (stream.hasNextLine() && active) {
final String line = stream.nextLine;
destination.add(line);
}
}
try {
stream.close();
} catch (IOException e) {
// Log somewhere
}
}
}
將它放到它自己的線程中(或者作爲線程或執行程序池的一部分,實際上),並且使應用程序的其餘部分對於此代碼無阻塞。 預計這將阻止等待從stream.hasNextLine()
更新。如果您不希望主動輪詢隊列,但以其他方式處理更新,則甚至可以提供BlockingQueue
。
然後你可以做這樣的事情的輸出:
public class QueuedPrinter implements Runnable {
private final Queue<String> input;
private final PrintStream destination;
private volatile boolean active;
public QueuedPrinter(Queue<String> input, PrintStream destination) {
this.input = input;
this.destination = destination;
}
public void shutdown() {
active = false;
}
public void run() {
while(active) {
final String line = input.poll();
if (line != null && active) {
destination.println(line);
}
}
}
}
請注意,我沒有測試過這一點,你可能要稍微調整一下事情經過其他異常。您可能需要添加額外的錯誤檢查代碼(想到空處理)。此外,這不是完全線程安全,但對於大多數用途可能是'夠用'。
定義'卡住'。套接字是否允許異步通信?你內在的「catch」條款在哪裏,或者說有什麼意義?不要一攬子捕捉所有例外情況 - 只能捕捉那些可以說明的情況(應用程序的最高級別除外)。不要使用'while(true)' - 檢查一些條件,這樣可以安全地關閉循環;目前用戶需要通過某種線程管理器(比如TaskManager)來終止線程,這不是一個愉快的前景。 –
通過卡住我的意思是它不會完成循環,並等待流的輸出。只有在客戶端輸出時,循環纔會完成。我已經修復了try/catch語句,while(true)循環不是問題。 – mudassir
這表明從'socket.getInputStream()'返回的流是'阻塞' - 也就是說,它等待輸入。您可能需要執行以下操作之一:1)將最初接收到的流包裝成不會阻塞的流2)爲套接字設置「TIMEOUT」選項(並捕獲產生的異常)3)使用線程和隊列,你的程序的其餘部分可以繼續,而不管輸入套接字的狀態如何(這可能是最好的選擇,並且可以與其他結合起來)。 –