【问题标题】:Why does this code wait 1000ms instead of 500ms?为什么这段代码等待 1000 毫秒而不是 500 毫秒?
【发布时间】:2021-08-24 01:42:55
【问题描述】:

我不明白这段代码如何打印 1000 而不是 500。我缺少什么吗?

    PipedOutputStream writer = new PipedOutputStream();
    PipedInputStream reader = new PipedInputStream();
    writer.connect(reader);
    BufferedReader stream = new BufferedReader(new InputStreamReader(reader));

    ScheduledExecutorService thread = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder().build());
    thread.schedule(() -> {
        try {
            Thread.sleep(500);
            writer.write("test\n".getBytes(StandardCharsets.UTF_8));
        } catch (InterruptedException | IOException ignored) {
        }
    }, 0, TimeUnit.MILLISECONDS);

    long startTime = System.currentTimeMillis();
    stream.readLine();
    long duration = System.currentTimeMillis() - startTime;
    System.out.println(duration);

【问题讨论】:

  • 假设PipedOutputStreamOutputStream的子类,在给定的代码中它永远不会被刷新,这可能会在第二次调度任务时隐式发生,导致等待时间为1000毫秒在BufferedReader 实际接收到一些输入之前。
  • @Izruo 就是这样,冲洗作家解决了这个问题。虽然这不是 scheduleAtFixedRate 只是调度所以任务不会运行两次。你能把这个写成答案让我接受吗?
  • 我不确定您为什么期望 stream.readline() 的时间为 500 毫秒。您是否希望 readLine() 阻塞与预定线程完成的时间一样长?假设您在写入后刷新,那么 duration至少 但可能超过 500 毫秒。我希望您不要依赖 duration 来获得特定的值范围。

标签: java multithreading io stream


【解决方案1】:

假设PipedOutputStreamOutputStream 的子类,在给定的代码中它永远不会被刷新。

由于我们不知道PipedOutputstream 的确切缓存或刷新行为,它可能发生test\n 的字节在等待过程之后没有立即写入连接的PipedInputStream 500 ms 已完成。相反,它会在稍后将第一块数据转发到其连接的接收器。

再次假设 PipedOutputStreamOutputStream 的子类,刷新流将修复此行为。

try {
    Thread.sleep(500);
    writer.write("test\n".getBytes(StandardCharsets.UTF_8));
    writer.flush();
} catch (InterruptedException | IOException ignored) {
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-13
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2015-05-02
    • 2021-02-26
    相关资源
    最近更新 更多