ホームページ  >  記事  >  Java  >  COW メカニズムと関連クラスの紹介

COW メカニズムと関連クラスの紹介

不言
不言転載
2019-03-02 14:28:402438ブラウズ

この記事の内容は COW の仕組みと関連クラスの紹介であり、一定の参考価値がありますので、困っている方は参考にしていただければ幸いです。

COW メカニズムには関連クラスがあります

Vector と SynchronizedList

ArrayList は Vector の置き換えに使用され、Vector はスレッドセーフなコンテナーであることがわかっています。コンテナを安全にするために、ほぼすべてのメソッド宣言に synchronized キーワードが追加されるからです。 Collections.synchronizedList(new ArrayList()) を使用して ArrayList をスレッドセーフにする場合、ほぼすべてのメソッドで synchronized キーワードが追加されますが、これはメソッドの宣言ではなくメソッド内部で追加されます。

Vector または SynchronizedList のマルチスレッド for ループ反復では、削除および取得操作を実行すると、配列添字エラー例外が発生します。

JDK5 以降、Java では、コレクションの走査に for-each (反復子) を使用することが推奨されています。利点は、それが簡単で、配列インデックスの境界値が 1 回だけ計算されることです。 for-each (イテレータ) を使用して上記の操作を実行すると、ConcurrentModificationException がスローされます。

上記の問題を完全に解決したい場合は、トラバースする前にロックを追加できます:

コンテナをトラバースするときにロックを追加する必要があります。遅い? 。確かにかなり遅いです。ロックの粒度が大きすぎるためです。

CopyOnWriteArrayList は同期 List の代替であり、CopyOnWriteArraySet は同期 Set の代替です。

Hashtable と Vector はロックの粒度が大きい (メソッド宣言で直接同期を使用する) ConcurrentHashMap と CopyOnWriteArrayList はロックの粒度が小さい (スレッド セーフを実現するためにさまざまなメソッドを使用する。たとえば、ConcurrentHashMap は cas lock 、 volatile を使用することがわかっています) JUC のスレッド セーフ コンテナは、トラバーサル中に ConcurrentModificationException をスローしません。したがって、一般的に言えば、古い A 世代を使用する代わりに、JUC パッケージで提供されるスレッド セーフ コンテナを使用します。スレッドセーフなコンテナーの。

CopyOnWriteArrayList の実装原理

CopyOnWriteArrayList は (ArrayList に対して) スレッドセーフなコンテナーであり、最下層は配列をコピーすることによって実装されます。 CopyOnWriteArrayList はトラバース時に ConcurrentModificationException をスローせず、トラバース中に追加の要素をロックする必要はありません。要素は null にすることができます

/** 可重入锁对象 */
    final transient ReentrantLock lock = new ReentrantLock();
    /** CopyOnWriteArrayList底层由数组实现,volatile修饰 */
    private transient volatile Object[] array;

    final Object[] getArray() {
        return array;
    }
    final void setArray(Object[] a) {
        array = a;
    }
    // 初始化CopyOnWriteArrayList相当于初始化数组
    public CopyOnWriteArrayList() {
        setArray(new Object[0]);
    }

CopyOnWriteArrayList の最下層は配列であり、ロックは ReentrantLock によって行われます。

コードから次のことがわかります。add()、set()、remove()、および新しい配列のコピー時にロックされ、新しい配列で加算操作が完了し、配列が新しい配列をポイントします。配列 、ついにロックが解除されました。変更する場合、新しい配列がコピーされ、新しい配列内で変更操作が完了し、最後に新しい配列が配列変数によってポイントされます。書き込み用にロックされ、読み取り用にロックされない

CopyOnWriteArrayList の欠点

メモリ使用量: CopyOnWriteArrayList がデータの追加、削除、変更を頻繁に行い、add()、set() を頻繁に実行する場合、および Remove() は、より多くのメモリを消費します。

add()、set()、remove() などの各追加、削除、変更操作では配列をコピーする必要があることがわかっているためです。

データの一貫性: CopyOnWrite コンテナはデータの最終的な一貫性のみを保証できますが、データのリアルタイムの一貫性は保証できません。

上記の例からもわかります。たとえば、スレッド A は CopyOnWriteArrayList コンテナーのデータを反復しています。スレッド B は、スレッド A の反復ギャップ中に CopyOnWriteArrayList 部分のデータを変更しました (setArray() が呼び出されました)。ただし、スレッド A は元のデータを反復処理します。

以上がCOW メカニズムと関連クラスの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。

関連記事

続きを見る