【问题标题】:How to synchronize file wise file writer object?如何同步文件明智的文件写入器对象?
【发布时间】:2015-12-24 01:32:54
【问题描述】:

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

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

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

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

假设有两个线程 T1 和 T2。 T1 线程正在写入 OneFile.txt。 T2 线程想要写入 twoFile.txt,然后 T2 线程阻塞,因为 T1 正在写入 OneFile.txt。 T2 不应该被阻塞,因为它要写 twoFile.txt。

请建议什么是好的架构。 请为此提供示例代码。

【问题讨论】:

  • 完全按照标题中的内容去做。在 FileWriter 中同步。

标签: java multithreading performance thread-safety threadpool


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    像你这样的接缝可以使用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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多