我正在尝试运行一个超时的外部进程,并读取它产生的所有输出。事实证明,这是一项令人惊讶的艰巨任务。我的基本策略是使用ProcessBuilder启动一个进程,并在主线程中读取它的输出。另一个线程被隔离,等待超时到期,并(如果需要)在我传递它的进程上调用close(),在也传递给它的进程上调用ReadableByteChannel ()。
这在打印无限输出的进程上似乎工作得很好,甚至可以得到预期的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
}
}我永远看不到第二个print语句,我的测试永远挂起。javadoc说close()可以阻止正在运行的另一个close,但是在我的代码中没有对close()的其他调用。还有什么会导致这种情况呢?
发布于 2011-07-22 08:26:29
测试永远挂起的原因是如果ReadableByteChannel.read()阻塞了它,ReadableByteChannel.close()就会阻塞它。
从文档中可以看出,处于阻塞模式的ReadableByteChannel (默认情况下,所有通道都是阻塞的)将一直阻塞,直到至少读取了一个字节(如果您的ByteBuffer中有空闲的字节),因此读取将是阻塞的。
如果您阅读了类java.nio.channels.Channels$ReadableByteChannelImpl (在Channels.java中找到)的代码,您将看到ReadableByteChannelImpl被注释为“不是真正可中断的”-显然,他们是认真的。
如果您调用Process.destroy(),这将终止一个没有产生任何输入的进程,并导致从您的读取线程抛出一个AsynchronousCloseException。
https://stackoverflow.com/questions/6778067
复制相似问题