我有一个静态的HashMap
,它在应用程序启动时填充,并每天刷新。
如何确保刷新期间没有其他线程可以访问 map ?
@ThreadSafe
public class MyService {
private static final Map<String, Object> map = new HashMap<>();
private MyDao dao;
public void refresh(List<Object> objects) {
map.clear();
map.addAll(dao.findAll()); //maybe long running routine
}
public Object get(String key) {
map.get(key); //ensure this waits during a refresh??
}
}
我是否应该引入一个在 refresh()
期间设置和清除的简单 boolean 锁
?或者还有更好的选择吗?或者同步
机制是一种可行的方法吗?
最佳答案
您可以使用 volatile map 并在填充后重新分配它:
public class MyService {
private static volatile Map<String, Object> map = new HashMap<>();
private MyDao dao;
public void refresh(List<Object> objects) {
Map<String, Object> newMap = new HashMap<>();
newMap.addAll(dao.findAll()); //maybe long running routine
map = newMap;
}
public Object get(String key) {
map.get(key); //ensure this waits during a refresh??
}
}
它是非阻塞的,从 newMap
到 map
的分配是原子的并确保可见性:任何后续对 get
的调用都将基于刷新后的 map 。
从性能角度来看,这应该可以很好地工作,因为 volatile 读取几乎与正常读取一样快。 volatile 写入稍微慢一点,但考虑到刷新频率,这应该不是问题。如果性能很重要,您应该运行适当的测试。
注意:您必须确保没有外部代码可以访问 map
引用,否则该代码可能会访问过时的数据。
关于java - 如何在刷新期间锁定 HashMap ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28147889/