簡體   English   中英

從 InputStream 讀取 - 非阻塞忙等待 VS 阻塞超時?

[英]Reading from InputStream - non-blocking with busy waiting VS blocking with timeout?

任務是從 InputStream 中讀取數據並等待結果達到可配置的時間。

給定兩種選擇,哪一種更可取? 或者推薦另一個。

  1. 阻塞調用 read() 方法,您必須自己超時
  2. 對可用()的非阻塞調用,您必須使用忙等待和睡眠進行輪詢

    import java.io.IOException; import java.io.InputStream; import java.util.concurrent.*; public class MyClass { public static void main(String[] args) throws InterruptedException, ExecutionException, IOException { MyClass myClass = new MyClass(); final InputStream in = System.in; final long timeout = 1000; final int result = myClass.blockingWithTimeout(in, timeout); // final int result = myClass.nonBlockingBusyWait(in, timeout); System.out.println("Result " + result); } public int nonBlockingBusyWait(final InputStream is, long timeoutMs) throws IOException, InterruptedException { final long start = System.currentTimeMillis(); while (is.available() == 0 && (System.currentTimeMillis() < start + timeoutMs)) { Thread.sleep(1); } if (is.available() == 0) { return -1; } else { return is.read(); } } public int blockingWithTimeout(final InputStream is, long timeoutMs) throws InterruptedException, ExecutionException { ExecutorService es = Executors.newSingleThreadExecutor(); Future<Integer> future = es.submit((Callable<Integer>) is::read); try { return future.get(timeoutMs, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { return -1; } catch (InterruptedException | ExecutionException e) { throw e; } finally { future.cancel(true); } } }

這兩種方法都有缺陷。 使用available()您的程序可能會在 EOF 的情況下永遠掛起。 提交阻塞read() ,后台調用有可能在超時完成並消耗流中的數據。 因此數據會丟失。

當您的流是套接字流時,您可以在代碼中設置套接字超時並處理SocketTimeoutException 現代 Java 還為非套接字 I/O 類型提供異步 API。 你可以調用它的方法返回Future 但是,如果您決定取消或放棄 Future,則該頻道可能會被標記為不一致並拒絕進一步操作。

如果它是一些舊的 3rd 方 API,它返回一個黑盒 InputStream,你可以使用我的包裝器來獲得類似套接字的行為。 它節省了您在內部緩沖區中不消耗的字節: https : //gist.github.com/basinilya/a5392de106cd890a28742960bcc5cf8c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM