set()方法源码如下:
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(); } }
else分支那里的setArray()可能第一次看不知道这是干嘛用的,因为就CopyOnWriteArrayList容 器本身来说, 这个操作并没什么作用,它的作用更多的是如它的注释所写的那样, 'ensures volatile write semantics'
相关知识点
- volatile和线程重排序
- java内存模型和 happens-before
在上面介绍的happens-before知识的结尾处, 出现了 捎带同步(其实就是利用happens-before具有传递性的特点)(piggybacking on synchronization) 的技巧, 由于volatile会影响happens-before和重排序, 所以在CopyOnWriteArrayList中的set方法 更多的是用来保证外部依赖volatile语义的地方不会出现错误.
参考知识
第一次写东西,如有错误的地方欢迎批评指证. :)