说明一下,这边文章写得比较简单,只涉及到ReadWriteLock的使用,具体源码实现原理并不涉及。
1、使用场景:
首先我这边是实际开发中使用到了,开发的环境情况为:有一个数据中心(暂且当做一个Map集合),有两个子线程A、B,其中A线程每5秒钟从其他地方获取到新来的数据然后和数据中心里面的数据进行一个融合,然后B线程进行隔5分钟从数据中心取出Map集合并解析其中的数据,一开始测试没什么问题,但是测试多了发现有一定几率发生“java.util.ConcurrentModificationException”异常,也就是同一个对象同时被两个线程操作,原因为:当B线程取到数据并进行遍历解析数据时,A线程去操作了数据中心的Map集合,因为他们最终引用的对象是一个,所以产生了上述问题。
当时一开始想到的是,使用原型模式,进行Map的克隆(主要考虑到使用克隆的话属于牺牲内存,如果使用锁的话牺牲的是性能),而Map默认的是浅克隆(注意用的是HashMap,Map是个接口是没有克隆方法的),单独克隆后发现Map里面的对象还是引用的一个,所以需要把里面的对象也单独克隆(Map默认克隆是只克隆本身对象,如果map里面还有对象的话是不会克隆的),下面贴一下clone重写的方法。我边是直接重写的数据中心的clone方法,因为里面有Map集合;
# NetWorkDataBean :这个是数据中心,里面有三个Map集合this.udpMap、 this.tcpMap 、this.mediaMap
@Override
public Object clone() throws CloneNotSupportedException {
NetWorkDataBean bean = (NetWorkDataBean) super.clone();
if (null == this.udpMap) {
this.udpMap = new HashMap<>();
} else {
bean.udpMap = new HashMap<>();
for (Map.Entry<Long, Map<String, UDPNetworkAnalyBean>> entry : this.udpMap.entrySet()) {
Map<String, UDPNetworkAnalyBean> mediaMapOld = entry.getValue();
Long mediaKey = entry.getKey();
Map<String, UDPNetworkAnalyBean> mediaMapNew = new