ConcurrentHashMap修饰符的同步

发布于 2024-07-26 18:43:57 字数 567 浏览 5 评论 0原文

我想在 ConcurrentHashMap 的帮助下缓存一些 IO。 对二进制文件的修改也应该反映在缓存中。 由于缓存将由多个线程使用,因此所有 IO 操作都是同步的。 地图的修改位于同一synchronized 块内。 如下:

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

大致

synchronized(file) {
    file.writeRecord(index, record);
    map.put(index, record);
}

mapfile 都是私有的,从缓存类外部看不到。

如果缓存读取(即 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜清冷一曲。 2024-08-02 18:43:57

是的。 这基本上就是 ConcurrentHashMap 的要点。 来自文档

检索操作(包括get)
一般不会阻塞,所以可能会重叠
具有更新操作(包括 put
并删除)。 检索结果反映了
最近完成的结果
更新操作持有其
发病。

并来自包文档 :

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

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

Yup. This is basically the point of ConcurrentHashMap. From the documentation:

Retrieval operations (including get)
generally do not block, so may overlap
with update operations (including put
and remove). Retrievals reflect the
results of the most recently completed
update operations holding upon their
onset.

and from the package documentation:

A concurrent collection is
thread-safe, but not governed by a
single exclusion lock. In the
particular case of ConcurrentHashMap,
it safely permits any number of
concurrent reads as well as a tunable
number of concurrent writes.

(Both of those documentation pages have much more detail, of course. They're worth reading carefully.)

横笛休吹塞上声 2024-08-02 18:43:57

是的,由于 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.

蓝梦月影 2024-08-02 18:43:57

是的,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 相同)。 对于您的情况来说,这可能是问题,也可能不是问题。

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:

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

(the same for writeRecord/put). This might or might not be a problem in your case.

自此以后,行同陌路 2024-08-02 18:43:57

好吧,正如这里的每个人所说,这是线程安全的,因为在写入缓存和从缓存读取之间存在先发生的关系,但这可能没有意义,具体取决于您希望的其他保证。

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

您确实得到了写入的 indexrecord 对象的状态将被读取的状态,尽管如果其中任何一个是可变的,那么这可能是一个相当大的问题。无用的保证。

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 and record objects as written will be what will be read, although if either of these are mutable then that may be a fairly useless guarantee.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文