我们有一个多线程的java程序。多线程将写入文件,一个线程将从该文件读取。我正在寻找一些设计理念。同步是否必要?
答案 0 :(得分:5)
在这种情况下我会考虑同步。想象一下,2个线程(t1和t2)同时打开文件并开始写入它。第一个线程执行的更改被第二个线程覆盖,因为第二个线程是最后一个将更改保存到文件的线程。当线程t1写入文件时,t2必须等到t1完成它的任务才能打开它。
此外,如果您关心文件的最新可能更新,您应该将写入线程与读取文件的线程同步,以便在有任何线程写入文件时,读取线程应该等待。
答案 1 :(得分:5)
FileChannel在理论上是线程安全的。来自javadoc:
多个并发线程可以安全地使用文件通道。该 可以在Channel指定的任何时间调用close方法 接口。只有一个操作涉及渠道的位置或 可以在任何给定时间更改其文件的大小; 尝试在第一次操作时启动第二次此类操作 正在进行将阻止,直到第一个操作完成。其他 操作,特别是那些采取明确立场的操作,可以 同时进行;他们实际上是否这样做取决于 基础实施,因此未指明。
如果您可以使用这些,那么您可以使用内置同步,而不必编写自己的同步。
答案 2 :(得分:2)
如果同步并不重要,您可以让您的编写器在其自己的线程中运行,并允许其他线程将写入队列排队。虽然我认为首先要考虑的是写入文件是否真的是你想要做的。特别是在高流量情况下,拥有大量磁盘I / O可能效率不高。
答案 3 :(得分:1)
如果您想要多个读者和一个作家,那么您将寻找Read Write Lock或读写互斥。
但是你想要多个作家和一个读者。你怎么知道这些作家不会覆盖彼此的数据?它们是否以某种方式隔离?
答案 4 :(得分:0)
一旦多个线程访问共享数据,则需要同步。如果多个线程在没有某种形式的锁定的情况下写入同一个文件,那么最终可能会导致更新丢失问题。
在所有情况下阅读都不是一个大问题所以你需要考虑......如果一个线程正在读取文件并且同时另一个线程更新文件,那么阅读线程是否需要知道这个变化?如果是这样,你还需要锁定读取线程的文件。
答案 5 :(得分:0)
如果您有读者和作者或作家和作者的混合,则需要同步(锁定)。如果您只有读者,则不需要任何同步。
您不希望两个进程写入同一个文件,或者一个进程编写另一个进程正在读取的文件。
答案 6 :(得分:0)
在这种情况下,同步是必要的。 FileChannel对于防止文件被JVM外部的进程修改很有用:对于包含多个线程写入单个文件的应用程序,情况并非如此。 从(进一步向下)JavaDoc for FileChannel:
代表文件锁 整个Java虚拟机。他们是 不适合控制访问 一个文件由多个线程内的 相同的虚拟机。
有关在线程之间共享文件写入的策略的简要讨论,请参阅this post。