我正在尝试使用Channels.newChannel包装一个InputStream,以便支持中断。我已经看到了相互矛盾的信息,这是否会起作用。在ReadableByteChannelImpl中包含注释:// Not really interruptible
在ReadableByteChannelImpl中,在对InputStream.read进行阻塞调用之前,会调用AbstractInterruptibleChannel.begin,它会使用sun.misc.SharedSecrets.getJavaLangAccess().blockedOn设置一个新的Interruptible,从而关闭包装好的InputStream。
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将从阻塞的read调用抛出IOException,如果它被另一个线程关闭,那么ReadableByteChannelImpl将使包装的流可中断,这是真的吗?
发布于 2018-12-06 03:55:54
是的,差不多吧。Channels.newChannel()适配器返回ReadableByteChannelImpl实例,除非流是FileInputStream;在这种情况下,它返回FileChannel,这也是可中断的。
当您得到一个ReadableByteChannel时,您已经检查过的代码表明(并且测试确认)底层InputStream是由读阻塞的线程上的interrupt()异步关闭的。
它可以依赖于InputStream的实现,但是核心Java运行时中包含的实现将通过在读取线程中抛出异常来响应异步闭包。具体的异常类型会有所不同。
https://stackoverflow.com/questions/48430015
复制相似问题