Java 什么会导致ReadableByteChannel.close()阻塞?
我试图运行一个超时的外部进程,并读取它产生的所有输出。事实证明,这是一项惊人的艰巨任务。我的基本策略是使用ProcessBuilder启动一个进程,并在主线程中读取它的输出。另一个线程被分配出去,等待超时过期,并(如果需要)对我传递给它的ReadableByTechnel调用close(),对也传递给它的进程调用destroy() 这在打印无限输出的进程上似乎工作得很好,甚至可以获得预期的AsynchronousCloseException。但是,当针对一个只会无限休眠的程序进行测试时,线程会在关闭时阻塞:Java 什么会导致ReadableByteChannel.close()阻塞?,java,nio,Java,Nio,我试图运行一个超时的外部进程,并读取它产生的所有输出。事实证明,这是一项惊人的艰巨任务。我的基本策略是使用ProcessBuilder启动一个进程,并在主线程中读取它的输出。另一个线程被分配出去,等待超时过期,并(如果需要)对我传递给它的ReadableByTechnel调用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()的调用。还有什么原因会导致这种情况?测试永久挂起的原因是,如果ReadableByteChannel.read()阻止了ReadableByteChannel.close(),它将被阻止 从文档中可以看出,如果ByteBuffer中有一个字节空闲,则处于阻塞模式的ReadableByteChannel(默认情况下所有通道)将阻塞,直到至少读取一个字节,因此读取将被阻塞 如果您阅读java.nio.channels.channels类$ReadableByteChannelImpl(在channels.java中找到)的代码,您将看到ReadableByteChannelImpl被注释为“不是真正可中断的”——显然,他们的意思是这样的
如果调用Process.destroy(),则将终止未生成任何输入的进程,并导致从读取线程引发AsynchronousCloseException。完全正确,谢谢。我在关闭后调用destroy,由于您描述的所有原因,它都失败了。我有点失望,API并没有确切地说出真相,但我不能对结果提出异议。@Techannel ReadableByteChannel的API文档Josh Gagnon说“其他类型的I/O操作是否可以与读取操作同时进行取决于通道的类型”。