https://blog.csdn.net/weixin_39724194/article/details/107413655
解释:
因为写(add()方法)加了锁,读方法(get)没加锁。
关键字volatile保证了读的数据总是最新的。(其它线程修改数据后会主动通知有该数据缓存的线程)但是,如果add()不复制的话,会导致读写并发时(先读再写),修改了同一地址的list,该操作破坏了读的list 内部维持的一系列状态,从而使读的list抛出ConcurrentModificationException(并发修改)异常。所以就复制一份出来,修改完了,再将修改过的数组写入原来的数组对象中。
private transient volatile Object[] array; //CopyOnWriteArrayList的属性--数组对象
setArray(es); //修改过的数组写入原来的数组对象中
final void setArray(Object[] a) { array = a; } //方法
为什么换个新对象就可以,原来的对象修改数据却不行呢?
个人理解:
复制的话:读的A的数据,修改后数组对象变成B。那么A和B是无关的,不会造成结构乱了。
不复制的话:是找了对象A的数据,又修改了A的数据,最后发现找到的和修改后内存中的数组结构不一致。