什么可以导致ReadableByteChannel.close()阻止?

时间:2011-07-21 14:52:40

标签: java nio

我正在尝试使用超时运行外部进程并读取它产生的所有输出。这被证明是一项令人惊讶的艰巨任务。我的基本策略是使用ProcessBuilder启动一个进程并在主线程中读取它的输出。另一个线程是等待超时到期并且(如果需要)调用我传递的ReadableByteChannel上的close(),也传递给它的进程上的调用destroy()。

这似乎可以在打印无限输出的进程上正常工作,甚至可以获得预期的AsynchronousCloseException。但是,当针对一个程序进行测试时,该程序只是无限地睡眠关闭时的线程块:

private void terminateProcess() {
    try {
        System.out.println("About to close readChannel.");
        readChannel.close();
        System.out.println("Closed the readChannel.");
    } catch (IOException e) {
        // Not relevant
    }
}

我从未看到第二个打印声明,我的测试永远挂起。 javadoc说close()可以阻止另一个close正在运行,但是我的代码中没有其他的close()调用。还有什么可以导致这个?

1 个答案:

答案 0 :(得分:3)

测试永远挂起的原因是ReadableByteChannel.close()将阻止ReadableByteChannel.read()阻止它。

从文档中,阻塞模式下的ReadableByteChannel(默认情况下所有通道都将被阻塞),直到你的ByteBuffer中有一个字节空闲时读取至少一个字节,因此读取将被阻塞。

如果您阅读类java.nio.channels.Channels $ ReadableByteChannelImpl(在Channels.java中找到)的代码,您将看到ReadableByteChannelImpl被评为“不可中断” - 显然,它们意味着它。

如果你调用Process.destroy(),那将终止一个没有产生输入并导致从你的阅读线程中抛出AsynchronousCloseException的进程。