zoukankan      html  css  js  c++  java
  • java多线程:CopyOnWriteArrayList

    本文是对该博文的延伸

    为什么CopyOnWriteArrayList 可以不使用checkForComodification()呢?

    首先,CopyOnWriteArrayList 的迭代器在创建时是将数组中的元素复制了一遍的

    然后,CopyOnWriteArrayList 的add等操作也是copy一份现有数据,在现有数据上修改好,在把原有数据的引用改成指向修改后的数据。还加上了同步锁以避免多线程同时add

    public boolean addAll(int index, Collection<? extends E> c) {
                synchronized(CopyOnWriteArrayList.this.lock) {
                    this.rangeCheckForAdd(index);
                    Object[] oldArray = this.getArrayChecked();
                    boolean modified = CopyOnWriteArrayList.this.addAll(this.offset + index, c);
                    this.size += (this.expectedArray = CopyOnWriteArrayList.this.getArray()).length - oldArray.length;
                    return modified;
                }
            }
    

    相当于读写都是copy之后对副本进行的,而不直接对源数组进行。此外,数组还被声明为了volatile类型,这会要求,当线程 2 进行修改时,会导致线程 1 的工作内存中的缓存变量的缓存行无效(反映到硬件层的话,就是 CPU 的 L1 或者 L2 缓存中对应的缓存行无效):

    private transient volatile Object[] array;
    

    这样做的话,对数组的修改就能在完成后同步到各个线程中,但是并不会直接影响线程中正在进行的利用迭代器的读(不会同时写的,有同步锁),因为读的是副本,不会过期,所以可以正常地继续从工作空间中间读自己拷贝的副本,虽然工作空间中的CopyOnWriteArrayList 变量已经过期了。但是此时读的就不是最新的内容了,所以说CopyOnWriteArrayList保证的是弱一致性

    这是我个人的理解,如有错误希望指正

  • 相关阅读:
    Mac OS系统安装pymssql 报错
    odoo源生打印【web report】
    《动手学深度学习》task05课后习题
    《动手学深度学习》task05笔记
    《动手学深度学习》task03课后习题
    《动手学深度学习》task03笔记
    《动手学深度学习》task04笔记
    《动手学深度学习》task04课后习题
    《动手学深度学习》task01-02疑难杂症
    《动手学深度学习》task01-02笔记
  • 原文地址:https://www.cnblogs.com/jiading/p/12454903.html
Copyright © 2011-2022 走看看