>我试图使用Channels.newChannel
来包装输入流以支持中断。我看到了相互矛盾的信息,这是否有效。在 ReadableByteChannelImpl 中包含注释:// Not really interruptible
在ReadableByteChannelImpl
中,在对InputStream.read
进行阻塞调用之前,调用AbstractInterruptibleChannel.begin
,它使用sun.misc.SharedSecrets.getJavaLangAccess().blockedOn
设置一个新的Interruptible
,这将关闭包装的输入流。
protected final void begin() {
if (interruptor == null) {
interruptor = new Interruptible() {
public void interrupt(Thread target) {
synchronized (closeLock) {
if (!open)
return;
open = false;
interrupted = target;
try {
AbstractInterruptibleChannel.this.implCloseChannel();
} catch (IOException x) { }
}
}};
}
blockedOn(interruptor);
Thread me = Thread.currentThread();
if (me.isInterrupted())
interruptor.interrupt(me);
}
如果一个InputStream
在被另一个线程关闭时会从阻塞的读取调用中抛出IOException
,那么ReadableByteChannelImpl
会使包装的流中断,这是真的吗?
是的,差不多。Channels.newChannel()
适配器返回一个ReadableByteChannelImpl
实例,除非流是FileInputStream
;在这种情况下,它返回一个 FileChannel
,这也是可中断的。
当您确实得到一个ReadableByteChannel
时,您已经检查过的代码表明(并且测试确认(底层InputStream
被读取中阻塞的线程上的interrupt()
异步关闭。
它可以依赖于InputStream
的实现,但是核心Java运行时中包含的实现将通过在读取线程中抛出异常来响应异步闭包。异常的具体类型会有所不同。