我需要创建一个文件系统管理器(或多或少),它可以读取或写入文件数据。
我的问题是如何处理并发?
我可以做类似
的事情public class FileSystemManager {
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public byte[] read(String path) {
readWriteLock.readLock().lock();
try {
...
} finally {
readWriteLock.readLock().unlock();
}
}
public void write(String path, byte[] data) {
readWriteLock.writeLock().lock();
try {
...
} finally {
readWriteLock.writeLock().unlock();
}
}
}
但这意味着所有对write(例如)的访问都将被锁定,即使第一次调用是针对/tmp/file1.txt而第二次调用是针对/tmp/file2.txt。
任何想法如何解决这个问题?
答案 0 :(得分:4)
通常,这种锁定发生在java级别之下。你真的打算阅读和编写相同的文件和目录吗?实现目录?
现在有很多不安全的线程代码可能会随着线程开始真正在多核硬件上运行而开始爆炸。
我的建议是通过消息传递来管理并发。如果这是一项教育活动,您可以自己动手,或者使用数以万计的排队和消息系统。在这种系统中,您只有一个读取器/写入器进程,但可能有许多客户端。您无需进行文件和线程并发管理。
消息传递范例的一个优点是,为负载平衡创建分布式系统会更容易得多。
答案 1 :(得分:3)
你不能为每个Path创建一个不同的对象,然后使用同步块并同步“this”吗?
答案 2 :(得分:3)
您可以将ReadWriteLock实例存储在路径上键入的地图中,只需确保您可以正确地访问地图(可能使用ConcurrentHashMap)。
如果您真的关心使用操作系统原语锁定文件,您可能会尝试使用java.nio.FileChannel。这支持文件区域的细粒度锁定等。另请查看java.nio.channels.FileLock。
答案 3 :(得分:2)
我会深入研究Java 5和java.util.concurrent包。我还建议阅读Brian Goetz'"Java Concurrency in Practice"。