gpt4 book ai didi

java - 合作流消费者的设计思路?

转载 作者:搜寻专家 更新时间:2023-11-01 03:25:47 26 4
gpt4 key购买 nike

假设以下场景:

我们有一个来自某个库的 Java 类,它使用字节流,比如说一些 XML 解析器 XmlParser1,它公开了一个方法 xmlParser1.parse(inputStream);该方法通常会在一次调用中吃掉所有字节,最终阻塞。我们还有另一个来自其他库的类,它执行类似的操作,但实现不同:XmlParser2xmlParser2.parse(inputStream)。现在,我们要使用两个解析器解析单个流

我的第一个回答是:我们完蛋了。由于我们无法控制每个类如何使用流,我们所能做的就是将所有字节缓冲到内存中或缓冲到临时文件(或打开/重新打开它,如果可能)。这些消费者的 API 本质上是非合作的。

现在,假设我们控制了XmlParser1(实现和签名),我们希望以更灵活和协作的方式对其进行编码,以便调用者能够以某种合理和合理的方式实现上述行为有效的方式......你有什么建议?

我正在考虑的一些替代方案:

1) 让 XmlParser1 实现 FilterInputStream,这样当某个类 (XmlParser1) 试图从它读取一些字节时,它会在内部解析它必须做什么(迭代,也许有一些合理的缓冲)并且还返回原始字节。 (这并不完全对应于 FilterInputStream 概念,我会说)。这样,客户端代码可以简单地链接解析器:

   public class XmlParser1 extends FilterInputStream {
public XmlParser1(InputStream rawInputStream) { ... }
public int read(byte[] b, int off, int l) throws IOException {
// this would invoke the underlying stream read, parse internall the read bytes,
// and leave them in the buffer
}
}

XmlParser1 parser1 = new XmlParser1(inputstream);
XmlParser2 parser2 = new XmlParser2(parse);
parser2.parse(); // parser2 consumes all the input stream, which causes parser1 to read an parse it too

2) 与其将 XmlParser1 视为字节的消费者,不如将其视为接收器:我们不会让它吃东西本身就是字节,我们将用勺子喂它。因此,我们可以使用 xmlParser1.parse(inputStream) 而不是xmlParser1.write(byte[]) ... 也就是说,我们不是将其传递给 InputStream,而是将其设为 OutputStream。这将允许客户端创建一个 TeeInputStream,它将字节透明地传递给 XmlParser2 类,同时调用 XmlParser1.write()

请注意,在任何情况下我们都不需要单独的线程。

我不确定哪一个(如果有的话)在概念上更可取,是否有更好的选择。在我看来,这是一个应该已经讨论过的设计问题,但我发现的不多——不一定局限于 Java。欢迎提出意见和引用。

最佳答案

假设两个解析器在两个独立的线程中运行,它可能是这样的(不是工作代码)

public class Test extends FilterInputStream {
byte[] buf = new byte[8192];
int len;
Thread thread = null;

@Override
public synchronized int read(byte[] b, int off, int l) throws IOException {
while (thread == Thread.currentThread() && len > 0) {
thread.wait();
}
if (len > 0) {
System.arraycopy(buf, 0, b, off, l);
len = 0;
return l;
}
len = super.read(b, off, l);
System.arraycopy(b, off, buf, 0, len);
thread = Thread.currentThread();
notify();
return len;
}

也就是说,#1 读取字节并将它们保存在 buf 中,#1 的下一次尝试将被阻止,直到#2 从缓冲区中读取所有字节

关于java - 合作流消费者的设计思路?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14150256/

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