gpt4 book ai didi

Java ReadableByteChannel Impl 行为不一致

转载 作者:太空宇宙 更新时间:2023-11-04 08:57:26 25 4
gpt4 key购买 nike

当我使用 Channels.newChannel(is) 从 InputStream 创建 channel 时,java 标准库返回一个 ReadableByteChannelImpl,即:

   private static class ReadableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements ReadableByteChannel
{
InputStream in;
private static final int TRANSFER_SIZE = 8192;
private byte buf[] = new byte[0];
private boolean open = true;
private Object readLock = new Object();

ReadableByteChannelImpl(InputStream in) {
this.in = in;
}

public int read(ByteBuffer dst) throws IOException {
int len = dst.remaining();
int totalRead = 0;
int bytesRead = 0;
synchronized (readLock) {
while (totalRead < len) {
int bytesToRead = Math.min((len - totalRead),
TRANSFER_SIZE);
if (buf.length < bytesToRead)
buf = new byte[bytesToRead];
if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once
try {
begin();
bytesRead = in.read(buf, 0, bytesToRead);
} finally {
end(bytesRead > 0);
}
if (bytesRead < 0)
break;
else
totalRead += bytesRead;
dst.put(buf, 0, bytesRead);
}
if ((bytesRead < 0) && (totalRead == 0))
return -1;

return totalRead;
}
}

protected void implCloseChannel() throws IOException {
in.close();
open = false;
}
}

正如您所看到的,它在第一次调用 read(ByteBuffer dst) 时会阻塞,并且不会再次阻塞。请参阅:

           if ((totalRead > 0) && !(in.available() > 0))
break; // block at most once

这种奇怪行为背后的原因是什么?

此外,扩展 AbstractInterruptibleChannel 而不实际使该 channel 真正可中断的动机是什么?

最佳答案

如果它已经读取至少一个字节并且基础流宣布没有字节available,则它不会阻塞。 。请注意InputStream#available()即使某些字节可用,也可以返回零,但它不应该 promise 比可以在不阻塞的情况下读取的字节数更多的字节。因此,这个ReadableByteChannel努力读取至少一个字节 - 假设提供 ByteBuffer至少有一个字节的空间——并且这样做后,不会尝试再次读取底层流,除非该流 promise 有更多字节可用而不会阻塞。

至于为什么ReadableByteChannelImpl延伸 AbstractInterruptibleChannel ,我怀疑是为了确保包裹的InputStream调用 Channel#close() 将正常关闭,其合约进一步细化为 InterruptibleChannel#close() 。扩展AbstractInterruptibleChannel允许ReadableByteChannelImpl借用其线程安全的开闭状态防护。

正如您所说,这有点虚假广告,并不是真正可中断的,但它可以容忍从单独的线程关闭,并使这样做具有幂等性。

关于Java ReadableByteChannel Impl 行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1894727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com