首页 新闻 会员 周边

CopyOnWriteArrayList类set方法疑惑

0
[已解决问题] 解决于 2017-04-25 18:49

在CopyOnWriteArrayList类的set方法中有一段setArray(elements)代码,实际上这段代码并未对elements做任何改动,实现的volatile语意并不对CopyOnWriteArrayList实例产生任何影响,为什么还是要保留这行语句?

public E set(int index, E element) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        E oldValue = get(elements, index);

        if (oldValue != element) {
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len);
            newElements[index] = element;
            setArray(newElements);
        } else {
       // 就是这一段代码
setArray(elements); } return oldValue; } finally { lock.unlock(); } } private E get(Object[] a, int index) { return (E) a[index]; } final void setArray(Object[] a) { array = a; }
狼爷的主页 狼爷 | 小虾三级 | 园豆:1204
提问于:2017-04-22 18:02
< >
分享
最佳答案
0

目的就是让另外一个线程在get时能马上读到更新后的值。作者在代码上加了一句解释,Not quite a no-op; ensures volatile write semantics,意思是说这行不完全是一个空操作,而是用来确保volatile的写语义。volatile的写语义之一就是插入一个lock前缀的指令,让volatile所修饰字段的缓存行(cache line)无效。一旦cache line无效,getArray时,必须先重新填充cache line,这样处理器就不会使用当前处理器缓存行里的旧值。

狼爷 | 小虾三级 |园豆:1204 | 2017-04-23 14:12

可问题是,根本就没有修改任何东西,即使你从cache行中直接读取有有什么不一样呢?大佬,我感觉我还是不能理解,望赐教

wtgiiwtg | 园豆:200 (初学一级) | 2022-08-14 19:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册