假設您的流不是由支持套接字(所以你不能使用Socket.setSoTimeout()),我認爲解決這類問題的標準方法是使用Future。
假設我有以下的執行和流:
ExecutorService executor = Executors.newFixedThreadPool(2);
final PipedOutputStream outputStream = new PipedOutputStream();
final PipedInputStream inputStream = new PipedInputStream(outputStream);
我有筆者,然後寫入一些數據寫入最後一塊數據,並關閉流之前等待5秒:
Runnable writeTask = new Runnable() {
@Override
public void run() {
try {
outputStream.write(1);
outputStream.write(2);
Thread.sleep(5000);
outputStream.write(3);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
executor.submit(writeTask);
閱讀本文的正常方法如下。讀出將無限期地阻止對數據等這樣就完成了5秒:
long start = currentTimeMillis();
int readByte = 1;
// Read data without timeout
while (readByte >= 0) {
readByte = inputStream.read();
if (readByte >= 0)
System.out.println("Read: " + readByte);
}
System.out.println("Complete in " + (currentTimeMillis() - start) + "ms");
輸出:
讀:1
閱讀:2
閱讀:3
在5001ms完成
如果還有一個更基本的問題,比如作者沒有迴應,讀者會永遠屏蔽。如果我包裹讀取在以後的,我可以然後控制超時如下:
int readByte = 1;
// Read data with timeout
Callable<Integer> readTask = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return inputStream.read();
}
};
while (readByte >= 0) {
Future<Integer> future = executor.submit(readTask);
readByte = future.get(1000, TimeUnit.MILLISECONDS);
if (readByte >= 0)
System.out.println("Read: " + readByte);
}
輸出:
讀:1
閱讀:2
在線程異常(FutureTask.java:91)「main」java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask $ Sync.innerGet(FutureTask.java:228) at java.util.concurrent.FutureTask.get(FutureTask.java:91) 在test.InputStreamWithTimeoutTest.main(InputStreamWithTimeoutTest.java:74)
我能趕上TimeoutException異常,做我想要的清理。
可能重複的[是否有可能從一個InputStream超時讀取?](http://stackoverflow.com/questions/804951/is-it-possible-to-read-from-a-inputstream-with -a超時) –
NFS timemouts是一個可以追溯到30年的問題。這是我非常認爲的觀點,即應用程序不應該以任何方式使用共享文件系統。 – EJP