gpt4 book ai didi

java - 从 InputStream 读取 - 忙等待的非阻塞 VS 超时的阻塞?

转载 作者:行者123 更新时间:2023-11-30 05:47:14 26 4
gpt4 key购买 nike

任务是从 InputStream 读取并等待结果,直到达到可配置的时间。

给定两个选项,哪一个更可取?或者建议另一种。

  1. 阻止调用 read() 方法,您必须自己超时
  2. 对 available() 的非阻塞调用,您必须使用繁忙等待和 sleep 来轮询该调用

    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,该 channel 可能会被标记为不一致并拒绝进一步操作。

如果是一些旧的第 3 方 API 返回黑盒 InputStream,您可以使用我的包装器来获取类似套接字的行为。它节省了内部缓冲区中不消耗的字节:https://gist.github.com/basinilya/a5392de106cd890a28742960bcc5cf8c

关于java - 从 InputStream 读取 - 忙等待的非阻塞 VS 超时的阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54635112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com