加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 同步不经常更新的hashmap的最佳方法

发布时间:2020-12-15 04:18:48 所属栏目:Java 来源:网络整理
导读:我有一个我们在应用程序中使用的HashMap.在应用程序初始加载期间,数据将从数据库中填充,然后始终只读取并且永远不会更新.将有多个线程不断读取数据.由于数据永远不会更新,我们目前不使用任何同步,只使用HashMap.我们现在定义的方式是: private volatile Map
我有一个我们在应用程序中使用的HashMap.在应用程序初始加载期间,数据将从数据库中填充,然后始终只读取并且永远不会更新.将有多个线程不断读取数据.由于数据永远不会更新,我们目前不使用任何同步,只使用HashMap.我们现在定义的方式是:

private volatile Map<Integer,MyData> myMap = new HashMap<>();

现在,我们希望每天通过从数据库重新填充来更新地图中的数据.我打算做的是将数据从数据库获取到本地地图,例如myLocalMap每天午夜说.一旦我将数据从DB加载到myLocalMap,我将交换myMap指向此.

所以我担心的是,在我做myMap = myLocalMap的时候,是否有可能从myMap读取数据的其他一些线程得到空的或意外的结果?
如果是,我将必须同步myMap.对于同步,我有以下选项:

synchronized(myMap) {} OR // synchronize all map get and update operations
ConcurrentHashMap OR
Collections.synchronizedMap(myMap)

但我对使用同步犹豫不决,因为那时我也正在同步所有的读取.我认为每天一次刷新同步地图将影响全天不断发生的地图读取.这是特别糟糕的,因为我的应用程序中有许多地图以这种方式读取和更新.有什么想法/评论?谢谢!

解决方法

At the point where I do myMap = myLocalMap,is there a possibility
that some other thread that is reading data from myMap get an empty or
unexpected result?

不,那里没有.为参考变量读取和写入are atomic,这意味着整个操作一次全部发生,并且在整个操作完成之前,结果对其他线程不可见.因此,从’myMap’读取的任何线程都将获得旧的myMap或新的myMap,但永远不会得到空的或不一致的结果.此外,在’myMap’上使用volatile关键字意味着所有线程始终都会知道新数据:如果myMap已更新,则在更新操作启动后启动的任何读取操作都将使用该更新值.

来自Oracle Java教程的支持文档:

  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  • any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable

Vogella:

If a variable is declared with the volatile keyword then it is
guaranteed that any thread that reads the field will see the most
recently written value.

同样来自Vogella的同一篇文章:

The Java language specification guarantees that reading or writing a
variable is an atomic operation

另请参阅this参考,特别是“清单3.使用volatile变量进行安全的一次性发布”,其中描述了与您的非常类似的场景.

顺便说一下,我同意Giovanni关于ConcurrentHashMap的观点.但在您的情况下,您不需要使用ConcurrentHashMap,因为所有更新都发生在单个事务中,而您只是将Map调整为指向新数据.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读