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不能保证您从映射中读取肯定已写入文件的内容
您确实可以保证索引
和记录
对象的写入状态将是读取的状态,尽管如果其中任何一个是可变的,那么这可能是一个相当无用的保证。感谢您确定了答案。感谢您确定了答案。