CopyOnWriteArrayListおよびCopyOnWriteArraySet

ArrayListコレクションとHashSetコレクションは、どちらもスレッドセーフではありません。対応するスレッドセーフクラスもあるものの、並行操作では問題が発生し、ConcurrentModificationException(並行変更例外)が報告されます。たとえば、ArrayListはスレッドセーフであるVectorに対応します。しかし、基になるソースコードを見ると、Vectorクラスの下部にある多くのメソッドが同期キーワードを追加してロックしてスレッドセーフを実現していることがわかります。これにより、効率が非常に低くなるため、通常、同時操作では使用されません。

コレクションスレッドセーフクラスを変換できるいくつかの方法を提供するツールのコレクションはスレッドセーフクラスです。たとえば、Collections.synchronizedListは、スレッドセーフなリストリストに変換できList<Integer> list = Collections.synchronizedList(new ArrayList<>());ます。 SynchronizedListクラス、およびSynchronizedListクラスは、java.util.Collectionsの静的内部クラスです。スレッドセーフティを保証できるのは、いくつかの一般的なメソッド処理で同期コードブロックが使用されるためです。Vectorと比較すると、スレッドセーフティの利点は、ロックのスコープが小さく、効率が高いことです。また、ロックするオブジェクトを柔軟に指定できます。 、および同期メソッドは、これまたはクラスのClassオブジェクトのみをロックできます。同じ方法で、Collections.synchronizedSetはスレッドセーフでないSetをスレッドセーフなSetに変換し、Collections.synchronizedMapはスレッドセーフでないMapをスレッドセーフなMapに変換します。すべて同じ

juc concurrencyでは、通常、CopyOnWriteArrayListはArrayListに対応するスレッドセーフクラスとして使用され、CopyOnWriteArraySetはHashSetに対応するスレッドセーフクラスとして使用されます

CopyOnWrite(COW)のアイデアは、コンピュータープログラミングの分野における最適化戦略です。つまり、メモリのブロックが変更されると、元のメモリブロックは直接書き込まれず、メモリのコピーが実行され、新しいメモリで書き込み操作が実行されます。書き込みが完了すると、元のメモリポインタがポイントされます。新しいメモリを使用すると、元のメモリを再利用できます。

CopyOnWriteArrayListとCopyOnWriteArraySetはCOWの考え方を使用しています。読み取り操作を実行すると、ロックは追加されません。読み取り操作にはデータの変更が含まれないため、スレッドのセキュリティ上の問題はなく、ロックを設定しないと効率が向上します。書き込み操作を実行すると、元のデータは直接変更されず、元のデータのコピーが変更されます。変更はこのコピーに対して行われ、書き込み後、変更されたコピーは元のデータに置き換えられます。これにより、書き込み操作が読み取り操作に影響しないことが保証されます。つまり、元のデータがまだ読み取られているため、書き込みの途中で読み取り操作がブロックされることはありません。さらに、ロックがaddメソッドに追加されて同期が保証され、マルチスレッド書き込み時に複数のコピーが回避されます。

要約すると、CopyOnWriteArrayListとCopyOnWriteArraySetは、読み取り操作がロックされていないため効率的であり、書き込み操作は毎回1つのコピーをコピーする必要があるため、より多くのメモリを消費するため、CopyOnWriteArrayListとCopyOnWriteArraySetは従来のスレッドセーフティを備えています。 Vectorクラスに対する利点は、Vectorクラスのすべての操作(追加、削除、変更、およびチェック)がロックされるのに対し、CopyOnWriteArrayListおよびCopyOnWriteArraySetは、追加、削除、変更、およびロックなしの読み取り操作に対してのみロックを追加することであり、より効率的です。

参照記事:https : //www.jianshu.com/p/9b6a4d0b94ac

おすすめ

転載: blog.csdn.net/can_chen/article/details/108686063