阅读sentinel的contextutil.java文件里的代码时,发现了一个在高并发场景下防止读取脏数据的操作,代码截取如下:
代码语言:javascript复制 private static volatile Map<String, DefaultNode> contextNameNodeMap = new HashMap<>();
Map<String, DefaultNode> newMap = new HashMap<>(contextNameNodeMap.size() 1);
newMap.putAll(contextNameNodeMap);
newMap.put(name, node);
contextNameNodeMap = newMap;
可以发现contextNameNodeMap是一个加了volatile关键字的,轻量级的线程之间可以互相看见的共享操作,下面四行代码其实就是一行代码contextNameNodeMap.put即可,但是为什么要这样做呢?是为了防止迭代稳定性问题,如果在改的时候有多个线程去进行读操作,那么就容易造成脏数据的读取,所以进行一次拷贝操作再重新赋值是一个很完美的解决办法。