如何同步文件明智的文件编写器对象?

时间:2015-09-26 08:56:43

标签: java multithreading performance thread-safety threadpool

目前我正在设计我的产品架构师并面临以下问题。

我有一个Queue,我在其中放置包含字符串和文件名的对象,其中应该写入字符串。

假设我有10个文件说OneFile.txt,twoFile.txt等。 现在我有三个OneFile.txt对象,队列中有五个对象ofFile.txt。

我有多个写入文件的线程。 现在,如果我同步文件编写器对象,那么它将阻止我的其他线程不写入同一文件。

假设有两个线程T1和T2。 T1 Thread正在写入OneFile.txt。 当T1写入OneFile.txt时,T2线程想要写入2File.txt然后T2线程块。 T2不应该是块,因为它想要写两个文件.txt。

请建议什么是好的建筑。 请提供示例代码。

2 个答案:

答案 0 :(得分:1)

并行编写是否是一个好主意并不明显。例如。在硬盘上,你通常会慢一点,在SSD上它可以更快,但这取决于你的情况(文件大小,在实际IO之前完成的处理等)。如果你需要它更快,它也不明显。

所以只要使用一个线程,直到你确定它是瓶颈。

答案 1 :(得分:0)

像你这样的接缝可以使用AsynchronousFileChannel(考虑到你运行的是Java 1.7+)。您将为每个需要写入的文件打开一个通道(请参阅open方法)。

这种类型的通道提供了异步写入操作,您可以在其中指定写入应该在文件中的哪个位置 - AsynchronousFileChannel#write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler)。这使您也可以对同一文本文件进行并行写入。你唯一需要做的就是照顾“下一个写作位置”。您可以通过为每个通道保留一个AtomicLong并使用CompareAndSwap执行并发更新来实现此目的:

以下是来自我们项目的CustomAsyncChannel类的代码的和平:

/**
 * Reserves the writing position in this channel with the given size. This method is thread
 * safe.
 * 
 * @param writeSize
 *            Size of writing that has to be done.
 * @return Returns the position where file should be written.
 */
public long reserveWritingPosition(long writeSize) {
    while (true) {
        long writingPosition = nextWritingPosition.get();
        if (nextWritingPosition.compareAndSet(writingPosition, writingPosition + writeSize)) {
            return writingPosition;
        }
    }
}

课程本身对你来说应该是一个很好的指南。请注意,写入只能部分完成,您可以在传递给写入操作的CompletionHandler中进行检查。