乱弾java同時(3)--CopyOnWriteArrayListとCopyOnWriteArraySet


CopyOnWriteArrayListは「書き込み時レプリケーション」ポリシーに基づくスレッドセキュリティの配列で、書き込みロックの読み取りと非ロックが特徴で、ConcurrentHashMapの原理を知ってから、その原理を理解するのは簡単です.2つの重要な方法を見てみましょう.
    public boolean add(E e) {
	final ReentrantLock lock = this.lock;
	lock.lock();
	try {
	    Object[] elements = getArray();
	    int len = elements.length;
	    Object[] newElements = Arrays.copyOf(elements, len + 1);
	    newElements[len] = e;
	    setArray(newElements);
	    return true;
	} finally {
	    lock.unlock();
	}
    }

    public E get(int index) {
        return (E)(getArray()[index]);
    }

    final Object[] getArray() {
        return array;
    }
コードから分かるように、配列に要素を追加するとき、配列全体をコピーして新しい配列にデータを挿入し、古い配列の代わりに新しい配列を使用することで、複数のスレッドが同じ時点で一致しないデータを読み取ることができず、挿入時にグローバルロックをかけたため、複数のスレッドが同時にデータを挿入できないことを保証します.この中でarrayの时に1つのvolatile変数、この点はとても重要で、挿入操作の最后にこのvolatile変数を设定して、volatileのJMMの中のhappens-beforeの意味から、すでにhpの伝达性に着いて、书く操作が完成した后に、书く操作が更新したデータがスレッドを読む时に见えることを保证しました.ConcurrentHashMapと同様に、CopyOnWriteArrayListも弱い一貫性しか保証できません.CopyOnWriteArrayListの書き込み操作は配列全体をコピーするため、時間の消費とGCに対する圧力全体が比較的大きいが、読み取り操作はロックがないため、読み取り操作が比較的効率的であり、読み取りスレッド間のブロックが発生しないため、この構成は書き込み操作よりはるかに多い読み取り操作のシーンに適している.
CopyOnWriteArraySetは完全にCopyOnWriteArrayListに基づいて実現されるが、ここではこれ以上説明しない.