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