java – 同步不经常更新的hashmap的最佳方法
我有一个我们在应用程序中使用的HashMap.在应用程序初始加载期间,数据将从数据库中填充,然后始终只读取并且永远不会更新.将有多个线程不断读取数据.由于数据永远不会更新,我们目前不使用任何同步,只使用HashMap.我们现在定义的方式是:
private volatile Map<Integer,MyData> myMap = new HashMap<>(); 现在,我们希望每天通过从数据库重新填充来更新地图中的数据.我打算做的是将数据从数据库获取到本地地图,例如myLocalMap每天午夜说.一旦我将数据从DB加载到myLocalMap,我将交换myMap指向此. 所以我担心的是,在我做myMap = myLocalMap的时候,是否有可能从myMap读取数据的其他一些线程得到空的或意外的结果? synchronized(myMap) {} OR // synchronize all map get and update operations ConcurrentHashMap OR Collections.synchronizedMap(myMap) 但我对使用同步犹豫不决,因为那时我也正在同步所有的读取.我认为每天一次刷新同步地图将影响全天不断发生的地图读取.这是特别糟糕的,因为我的应用程序中有许多地图以这种方式读取和更新.有什么想法/评论?谢谢! 解决方法
不,那里没有.为参考变量读取和写入are atomic,这意味着整个操作一次全部发生,并且在整个操作完成之前,结果对其他线程不可见.因此,从’myMap’读取的任何线程都将获得旧的myMap或新的myMap,但永远不会得到空的或不一致的结果.此外,在’myMap’上使用volatile关键字意味着所有线程始终都会知道新数据:如果myMap已更新,则在更新操作启动后启动的任何读取操作都将使用该更新值. 来自Oracle Java教程的支持文档:
Vogella:
同样来自Vogella的同一篇文章:
另请参阅this参考,特别是“清单3.使用volatile变量进行安全的一次性发布”,其中描述了与您的非常类似的场景. 顺便说一下,我同意Giovanni关于ConcurrentHashMap的观点.但在您的情况下,您不需要使用ConcurrentHashMap,因为所有更新都发生在单个事务中,而您只是将Map调整为指向新数据. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |