ConcurrentHashMap修饰符的同步
我想在 ConcurrentHashMap 的帮助下缓存一些 IO。 对二进制文件的修改也应该反映在缓存中。 由于缓存将由多个线程使用,因此所有 IO 操作都是同步的。 地图的修改位于同一synchronized
块内。 如下:
synchronized (file) {
file.deleteRecord(index)
map.remove(index);
}
大致
synchronized(file) {
file.writeRecord(index, record);
map.put(index, record);
}
map
和 file
都是私有的,从缓存类外部看不到。
如果缓存读取(即 map.get(index)
)不使用 synchronized
块,是否会保留线程安全?
正如我之前提到的,ConcurrentHashMap 用作映射实现。
I would like to cache some IO with the help of ConcurrentHashMap
. The modification on the binary file should be reflected in cache as well. Since the cache is going to be used by multiple threads all IO operations are synchronized. Modifications of map go inside the same synchronized
block. Which roughly looks like:
synchronized (file) {
file.deleteRecord(index)
map.remove(index);
}
and
synchronized(file) {
file.writeRecord(index, record);
map.put(index, record);
}
Both map
and file
are private and are not seen from outside the cache-class.
Is thread-safety preserved if cache reads, namely map.get(index)
, go without the synchronized
block?
As I mentioned earlier, ConcurrentHashMap
is used as map implementation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的。 这基本上就是 ConcurrentHashMap 的要点。 来自文档:
并来自包文档 :
(当然,这两个文档页面都有更多详细信息。它们值得仔细阅读。)
Yup. This is basically the point of
ConcurrentHashMap
. From the documentation:and from the package documentation:
(Both of those documentation pages have much more detail, of course. They're worth reading carefully.)
是的,由于 ConcurrentHashMap 实现,线程安全性一直保留到映射引用。
您存储在地图中的对象是另一回事。
Yes, thread safety is preserved down to the map references, thanks to the ConcurrentHashMap implementation.
The objects you store in the map are another story.
是的,ConcurrentHashMap 是线程安全的,因此读取(或写入)不需要您进行任何锁定。
但是,在您的示例中,您可能会得到以下事件序列:(
与 writeRecord/put 相同)。 对于您的情况来说,这可能是问题,也可能不是问题。
Yes, ConcurrentHashMap is thread safe, so reading (or writing) does not require any locking on your part.
However, in your example, you might end up with the following sequence of events:
(the same for writeRecord/put). This might or might not be a problem in your case.
好吧,正如这里的每个人所说,这是线程安全的,因为在写入缓存和从缓存读取之间存在先发生的关系,但这可能没有意义,具体取决于您希望的其他保证。
例如,除非您对文件进行 fsync,否则无法保证记录将写入磁盘,因此您可能无法从磁盘读取记录(取决于文件系统和其他一些因素)。 writeRecord/deleteRecord 和映射写入以及从映射读取之间也没有发生之前关系,因此 JMM 不保证您从映射中读取肯定已写入的内容文件。
您确实得到了写入的
index
和record
对象的状态将被读取的状态,尽管如果其中任何一个是可变的,那么这可能是一个相当大的问题。无用的保证。Well, as everyone here says, this is thread-safe in that you have a happens-before relationship between the write to the cache and the read from the cache, but that may be meaningless depending on what other guarantees you are hoping for.
For instance, unless you fsync the file there's no guarantee the record will be written to disk, so you may not read the record from disk (depending on the file-system and a few other factors). There is also no happens-before relationship between the writeRecord/deleteRecord and map write and the read from the map, so the JMM doesn't guarantee that you read something from the map that has definitely been written to the file.
You do get a guarantee that the state of the
index
andrecord
objects as written will be what will be read, although if either of these are mutable then that may be a fairly useless guarantee.