V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  Java

CopyOnWriteArrayList 类 set 方法疑惑

  •  
  •   amiwrong123 · 2020-06-27 10:55:17 +08:00 via Android · 2093 次点击
    这是一个创建于 1642 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 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 {
                    //就是这里
                    // Not quite a no-op; ensures volatile write semantics
                    setArray(elements);
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
    
    5 条回复    2020-06-27 12:58:47 +08:00
    BBCCBB
        1
    BBCCBB  
       2020-06-27 11:00:02 +08:00
    你百度一下很多讲这个得, 为了保证 volatile 得语义, 就是 happens before 规则里定义的..
    BBCCBB
        2
    BBCCBB  
       2020-06-27 11:01:56 +08:00
    有一个概念叫 `捎带同步`
    bigbyto
        4
    bigbyto  
       2020-06-27 12:45:45 +08:00
    简单来说就是保证 happens before 原则。jls 中 happens before 中有一条是
    A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
    对一个 volatile 变量的写入操作 happens before 其他线程对它的读操作。
    ky11223344
        5
    ky11223344  
       2020-06-27 12:58:47 +08:00
    应该是为了保证 set 方法之前的所有写操作能够被后续的读操作可见吧,volatile 规定了是这样的。不然可能来一个 set,element 参数和 oldValue 一样,然后没有 setArray 把所有该线程执行过的写操作刷到主内存,后续读就可能读不到 set 之前的所有写过的值了,这些值可能是同一个 object 里的属性,是多个线程的共享变量,可以是 volatile 也可以不是的,但只要他们之后有一个 volatile 属性被写了,后续对他们的读操作的可见性就有了保证。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1768 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 16:33 · PVG 00:33 · LAX 08:33 · JFK 11:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.