[英]Reading from InputStream - non-blocking with busy waiting VS blocking with timeout?
任务是从 InputStream 中读取数据并等待结果达到可配置的时间。
给定两种选择,哪一种更可取? 或者推荐另一个。
对可用()的非阻塞调用,您必须使用忙等待和睡眠进行轮询
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.