CopyOnWrite容器解決的併發問題

CopyOnWrite容器解決的併發問題

    先看這麼一段代碼:
    public static void main(String[] args) throws InterruptedException {
        List<String> a = new ArrayList<String>();
        a.add("a");
        a.add("b");
        a.add("c");
        final ArrayList<String> list = new ArrayList<String>(
                a);
        Thread t = new Thread(new Runnable() {
            int count = -1;

            @Override
            public void run() {
                while (true) {
                    list.add(count++ + "");
                }
            }
        });
        t.setDaemon(true);
        t.start();
        Thread.currentThread().sleep(3);
        for (String s : list) {
            System.out.println(s);
        }
    }

    首先一個線程對ArrayList進行遍歷操作,此間“休息”一段時間,另外一個線程進來,對List進行加入操作,此時“休息”後的線程繼續對list遍歷操作,運行爆出以下異常:


    這就是ArrayList在併發狀態下發生錯誤,如何解決呢?引出今日豬腳--CopyOnWrite容器。

    一、源碼

  1. put方法:
    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();
        }
    }
    該方法對put操作上鎖,並複製了原數組對象,對複製出來的數據進行修改操作,並在最後讓原引用指向新對象,如此一來,就解決了併發問題。
發佈了73 篇原創文章 · 獲贊 13 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章