5

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

我可以想到“工作面试”解决方案,使用线程、共享资源、同步块等......但我确信有更好的方法(是否有一个不错的小“延迟写入”库可以做到为了我?)

是否有任何java.util.concurrent软件包提供任何帮助?java.nio? 或者可能是 JMS/ActiveMQ?

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

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

编辑:

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

  • PipedOutputStream/ PipedInputStream(或PipedReader/ PipedWriter)和之间的实际区别是什么BlockingQueue
  • 并且最好将后者用于异步文件写入?(或者这是苹果与橙子的比较,如果是,我想知道为什么?)
4

3 回答 3

5

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

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

在并发线程中进行生产和消费最好使用 Java 的Executors框架来实现。

于 2012-05-02T05:46:59.703 回答
2

我可以想到“工作面试”解决方案,使用线程、共享资源、同步块等......但我确信有更好的方法(是否有一个不错的小“延迟写入”库可以做到为了我?)

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

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

可能。

java.nio?

可能。

或者可能是 JMS/ActiveMQ?

我对此表示怀疑……如果您的目标是写入本地文件。

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

那会有所帮助。但是您仍然需要实现读/写流的线程。


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

如果文件输出确实成为瓶颈,那么加速它的更简单方法是增加输出流缓冲区大小。这很简单——只需在BufferedOutputStream构造函数中添加一个额外的缓冲区大小参数。在进行重大重写之前,您应该尝试一下。

于 2012-05-02T06:11:17.830 回答
1

Java 7 在“NIO 2”中具有异步 I/O。

如果您不能使用 Java 7,坦率地说,我根本不会费心去尝试实现它。你可以做一些涉及期货的可怕事情,但如果不是负数,获得的收益可能为零。

于 2012-05-02T10:02:08.817 回答