【发布时间】:2019-02-11 16:36:38
【问题描述】:
任务是从 InputStream 中读取数据并在可配置的时间内等待结果。
给定两种选择,哪一种更可取?或者建议另一个。
- 阻止对 read() 方法的调用,您必须自己超时
-
对 available() 的非阻塞调用,您必须使用忙等待和睡眠来轮询它
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 的情况下,这是标准未指定的行为 -
永远不要比较
currentTimeMillis()。总是减去最后期限并与零进行比较。
标签: java inputstream blocking nonblocking