Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么CopyOnWriteArrayList.get不需要同步?_Java_Locking_Volatile_Java.util.concurrent - Fatal编程技术网

Java 为什么CopyOnWriteArrayList.get不需要同步?

Java 为什么CopyOnWriteArrayList.get不需要同步?,java,locking,volatile,java.util.concurrent,Java,Locking,Volatile,Java.util.concurrent,刚看了CopyOnWriteArrayList类,我想知道为什么它的get(…)方法不需要任何同步。add(…)和set(…)方法使用ReentrantLock更改互斥块中的基础数组。但是get(…)只返回原始的底层数组,没有任何同步。好的,底层数组声明为volatile: private volatile transient Object[] array; 但我不认为使用volatile会使任何同步变得多余。它只防止编译器缓存存储在数组中的引用。如果我理解为什么这里不需要同步,我可以用比以前

刚看了CopyOnWriteArrayList类,我想知道为什么它的get(…)方法不需要任何同步。add(…)和set(…)方法使用ReentrantLock更改互斥块中的基础数组。但是get(…)只返回原始的底层数组,没有任何同步。好的,底层数组声明为volatile:

private volatile transient Object[] array;
但我不认为使用volatile会使任何同步变得多余。它只防止编译器缓存存储在数组中的引用。如果我理解为什么这里不需要同步,我可以用比以前更少的锁争用来编写代码

谢谢,奥利弗,线索就在名字里(正如马克·罗特维尔所指出的)

当进行任何更改时,在单独的
对象[]
中进行更改,然后复制整个批次-“写入时复制”

当引用从旧的
对象[]
更改为新的
对象[]
时,内部
对象[]
是易变的,因此所有线程都会进行更改。

它使用了一个小“技巧”-当底层数组更改时,事件序列是:

  • 创建一个新数组
  • 填充新数组
  • 更改类持有的引用以指向新数组
  • 第三步写入
    private volatile transient Object[]数组-由于易变语义,在第三步之前所做的所有更改都是可见的


    因此,不仅新引用可见,而且新数组的内容也可见。(这就是诀窍)。

    类的名称是一个提示。@Mark rotterveel的可能重复:你是对的。谢谢。@MarkRotteveel我认为这篇文章中被接受的答案忽略了一个要点。另一个答案更准确。重复马克·罗特维尔指出的