PipedReader / PipedWriter的更好替代方案?

时间:2010-05-16 11:37:03

标签: java data-structures

我需要一个缓冲的char流,我在一个线程中编写,我从另一个线程中读取。 Right now我正在使用PipedReaderPipedWriter,但这些类会导致性能问题:当内部缓冲区为空时,PipedReader会执行wait(1000),这会导致我的应用程序明显滞后。

是否会有一些库与PipedReader / PipedWriter做同样的事情,但性能更好?或者我是否必须实施自己的车轮?

4 个答案:

答案 0 :(得分:6)

问题在于,当某些内容被写入PipedWriter时,它不会自动通知PipedReader有一些数据需要读取。当一个人试图读取PipedReader并且缓冲区为空时,PipedReader将循环并等待wait(1000)调用,直到缓冲区有一些数据。

解决方案是在向管道写入内容后始终调用PipedWriter.flush()。刷新所做的就是在阅读器上调用notifyAll()。有问题的代码looks like this的修复程序。

(对我而言,PipedReader / PipedWriter实现看起来非常类似于过早优化的情况 - 为什么不在每次写入时都通知?还有读者在一个活动循环中等待,每秒唤醒,而不是仅在有时才唤醒需要阅读的东西。代码还包含一些todo注释,它所做的读/写线程检测不够复杂。)

同样的问题似乎也出现在PipedOutputStream中。在我当前的项目中,手动调用flush()是不可能的(不能修改Commons IO的IOUtils.copy()),所以我通过为管道类创建low-latency wrappers来修复它。他们的工作比原来的课程要好得多。 : - )

答案 1 :(得分:1)

BlockingQueue周围包装char流API应该相当容易。

但是,我必须说,PipedReader使用轮询等待数据似乎很不正常。这是在某处记录的,还是以某种方式为自己发现了?

答案 2 :(得分:1)

@Esko Luontola,我一直在阅读sbt包中的代码,试图了解你在做什么。您似乎想要启动Process并将输入传递给它,并将操作的结果转到不同的位置。这完全正确吗?

我会尝试修改ReaderToWriterCopier中的主循环,这样就不会执行read() - 一个阻塞操作显然在涉及PipedReader时导致轮询 - 你明确地等待Writerflush。文档清楚明确flush会导致通知任何Reader

我不确定如何运行您的代码,因此我无法深入了解它。希望这会有所帮助。

答案 3 :(得分:0)

我实现了一些类似的东西,asked a question是否有其他人有更好的思考和测试代码。