CopyOnWriteArrayListとで追加操作のためのロックを獲得

ghostrider:

なぜ我々は、取得する必要がないReentrantのコード下記のとおりロックをCopyOnWriteArrayList我々は内の要素を追加したときList私たちは、元の配列のコピーを作成し、それを変更しています。我々は取得していない場合、私たちはどのような副作用を持つことができるlock最初の場所で?

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();
        }
    }
全おかげでガイ:

あなたは、マルチスレッドコンテキストでグローバル変数に任意の操作をしようと、それは両方になりたいされている場合、原子と確保メモリの可視性を使用すると、その操作の周りにロックを持っている必要があり、他のスレッドに。

ここでgetArray()グローバルインスタンスフィールドを返していますObject[] array

この例ではそう:

Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;

そこにこのコードブロックの周りに何もロックがなく、2つのスレッドが、それはそのスレッド1とスレッド2が起こる両方読んでも、その場合には、要素を追加しようとしていると仮定した場合と同じ値をlenと同じインデックスに新しい要素を割り当てます。

どのよう、これまで他のスレッドによって以前の値セットを上書きします最後に新しい値を代入を通します。

さらに説明するために、両方のスレッド1とスレッド2が同じ値の読みと言うlen今は1スレッドすることから、新しい配列を作成するために行くArrays.copyOf(elements, len + 1)と、変数の値を代入するelen、新しい配列の位置を。

スレッド1が使用して新しいアレイを設定することができます前にsetArray(newElements)スレッド2を一方の同じ値でこの処理を続行しますlenそれは新しい配列インスタンスを作成しますが、新しい要素が設定されたインデックスが同じであろうがlen、スレッド1によって使用されます。

スレッド2つの用途は、ときにsetArray(newElements)、スレッド1の後に新しい値を持つ新しい配列を設定するには、以前の配列値len番目のインデックスは、スレッド2による新たな要素セットで上書きされます。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=210551&siteId=1
おすすめ