用于在Java中编写异步文件的PipedOutputStream / PipedInputStream(或Reader / Writer)与BlockingQueue之间的异同

时间:2012-05-02 05:14:30

标签: java multithreading io

我正在尝试修改从数据库读取的串行程序,并将结果写入文件,这是以阻塞方式完成的,我认为我们可以通过内存缓冲区获得性能提升并拥有文件以异步方式写在“背景”中

我可以想到“求职面试”解决方案,使用线程,共享资源,同步块等... 但我确信有更好的方法(那里有一个很好的小“延迟写入”库会为我做吗?)

java.util.concurrent包中是否有任何帮助? java.nio?或者JMS / ActiveMQ?

PipedOutputStream / PipedInputStream作为我缓冲区的基础呢?

如何在Java中实现延迟/后台/缓冲/非阻塞/异步文件写入?

修改:

根据这些建议,并避免关闭此问题,(因为我认为它仍然基于答案评论和投票相关)这里是尝试使其更集中。 (我保留上面的原始问题所以答案仍将保留在上下文中,因为有一些非常好的答案)

  • PipedOutputStream / PipedInputStream(或PipedReader / PipedWriter)与BlockingQueue
  • 之间存在哪些实际差异?
  • 并且最好使用后者进行异步文件写入? (或者这是苹果与橘子的比较,如果是这样,我想知道为什么?)

3 个答案:

答案 0 :(得分:5)

您可能希望在生产者(数据库读取器)和使用者(文件编写者)之间使用有界阻塞队列。

Java的ArrayBlockingQueue完成了很好的工作。如果缓冲区已满,则生产者会阻塞,避免因消耗过多内存而出现任何问题。

使用Java的Executors框架最好地实现并发线程的生成和使用。

答案 1 :(得分:2)

  

我可以想到“求职面试”解决方案,使用线程,共享资源,同步块等...但我确信有更好的方法(那里有一个很好的小“延迟写入”库那里会为我做吗?)

我从未遇到过“延迟写入”库。但我想这实际上只是一个输出流/写入器写入队列或循环缓冲区,其中私有线程从队列/缓冲区读取并写入阻塞输出。这应该有效,但可能很难避免复制双重复制数据的成本。

  

是否有任何java.util.concurrent包提供任何帮助?

可能。

  

的java.nio?

可能。

  

或者JMS / ActiveMQ?

我怀疑它......如果你的目标是写一个本地文件。

  

PipedOutputStream / PipedInputStream作为我的缓冲区的基础怎么样?

这可能会有所帮助。但是你仍然需要实现读/写流的线程。


忽略了如何实现这一点的机制,我怀疑在这种情况下通过执行异步I / O不会获得显着的加速。如果您以当前形式分析应用程序,您可能会发现主要瓶颈是从数据库获取数据。写入文件可能会快几个数量级。如果是这种情况,则重叠的数据库和文件I / O不太可能显着提高速度。

如果文件输出确实成为瓶颈,那么加快速度的简单方法就是增加输出流缓冲区大小。这很简单 - 只需在BufferedOutputStream构造函数中添加一个额外的缓冲区大小参数即可。你应该在开始重大改写之前尝试一下。

答案 2 :(得分:1)

Java 7在'NIO 2'中具有异步I / O.

如果你不能使用Java 7,我就不会费心去实现它。你可以做一些涉及期货的可怕事情,但如果不是负面的话,获得的利益可能是零。