Java ConcurrentHashMap修改器的同步

Java ConcurrentHashMap修改器的同步,java,concurrency,synchronization,concurrenthashmap,Java,Concurrency,Synchronization,Concurrenthashmap,我想借助ConcurrentHashMap缓存一些IO。对二进制文件的修改也应该反映在缓存中。由于缓存将由多个线程使用,因此所有IO操作都是同步的。映射的修改进入相同的同步块中。大致上看起来像: synchronized (file) { file.deleteRecord(index) map.remove(index); } 及 map和file都是私有的,从缓存类外部看不到 如果缓存读取,即map.get(index),而不使用synchronized块,线程安全性是否得

我想借助
ConcurrentHashMap
缓存一些IO。对二进制文件的修改也应该反映在缓存中。由于缓存将由多个线程使用,因此所有IO操作都是同步的。映射的修改进入相同的
同步
块中。大致上看起来像:

synchronized (file) {
    file.deleteRecord(index)
    map.remove(index);
}

map
file
都是私有的,从缓存类外部看不到

如果缓存读取,即
map.get(index)
,而不使用
synchronized
块,线程安全性是否得到保护


正如我前面提到的,
ConcurrentHashMap
被用作映射实现。

是的。这基本上就是
ConcurrentHashMap
的要点。发件人:

检索操作(包括get) 通常不堵塞,因此可能会重叠 具有更新操作(包括put) 并移除)。检索反映了 最近完成的调查结果 更新保留在其上的操作 起病

从以下方面:

一个并发集合是 线程安全,但不受 单个排除锁。在
ConcurrentHashMap的特殊情况,
它安全地允许任何数量的
并发读取以及可调
并发写入的数量


(当然,这两个文档页面都有更多的细节。它们值得仔细阅读。)

是的。这基本上就是
ConcurrentHashMap
的要点。发件人:

检索操作(包括get) 通常不堵塞,因此可能会重叠 具有更新操作(包括put) 并移除)。检索反映了 最近完成的调查结果 更新保留在其上的操作 起病

从以下方面:

一个并发集合是 线程安全,但不受 单个排除锁。在
ConcurrentHashMap的特殊情况,
它安全地允许任何数量的
并发读取以及可调
并发写入的数量


(当然,这两个文档页面都有更详细的内容。它们值得仔细阅读。)

是的,由于ConcurrentHashMap实现,线程安全一直保留到映射引用


存储在地图中的对象是另一个故事

是的,由于ConcurrentHashMap实现,线程安全一直保留到映射引用


存储在地图中的对象是另一个故事

是的,ConcurrentHashMap是线程安全的,因此读取(或写入)不需要任何锁定

但是,在您的示例中,可能会出现以下事件序列:

file.deleteRecord(index);
map.get(index) // returns the mapping for index even though it has been deleted from file
map.remove(index);

(writeRecord/put与此相同)。在您的案例中,这可能是一个问题,也可能不是问题

是的,ConcurrentHashMap是线程安全的,因此读取(或写入)不需要任何锁定

但是,在您的示例中,可能会出现以下事件序列:

file.deleteRecord(index);
map.get(index) // returns the mapping for index even though it has been deleted from file
map.remove(index);

(writeRecord/put与此相同)。在您的案例中,这可能是一个问题,也可能不是问题

好吧,正如这里的每个人所说,这是线程安全的,因为在对缓存的写操作和从缓存中读取操作之间有一个“先发生后发生”的关系,但这可能毫无意义,这取决于您希望得到的其他保证

例如,除非您对文件进行fsync,否则无法保证将记录写入磁盘,因此您可能无法从磁盘读取记录(取决于文件系统和其他一些因素)。writeRecord/deleteRecord与映射写入和从映射读取之间也没有“先发生后发生”关系,因此JMM不能保证您从映射中读取肯定已写入文件的内容


您确实得到了一个保证,即写入的
索引
记录
对象的状态将是将要读取的,尽管如果其中任何一个是可变的,那么这可能是一个相当无用的保证。

好吧,正如这里的每个人所说,这是线程安全的,因为在对缓存的写操作和从缓存中读取操作之间存在“发生在之前”关系,但这可能没有意义,这取决于您希望得到的其他保证

例如,除非您对文件进行fsync,否则无法保证将记录写入磁盘,因此您可能无法从磁盘读取记录(取决于文件系统和其他一些因素)。writeRecord/deleteRecord与映射写入和从映射读取之间也没有“先发生后发生”关系,因此JMM不能保证您从映射中读取肯定已写入文件的内容


您确实可以保证
索引
记录
对象的写入状态将是读取的状态,尽管如果其中任何一个是可变的,那么这可能是一个相当无用的保证。

感谢您确定了答案。感谢您确定了答案。