ConcurrentSkipListSet内部動作、TreeSetとの違い

Aug 23 2020

私が理解している唯一の違いは、イテレータ間の違いです。SkipList持っている弱一貫性ながら、TreeSet持っているフェイルファスト。それ以外は、同期されたメソッドは内部に表示されませんSkipList(並行パッケージに含まれていますが)。

SkipList同期がない場合の同時実行について誰かに説明してもらえますか?それはどのような問題を解決するのに役立ちますか?また、イテレータ間のこの違い以外に、なぜそれを使用する必要があるのですか?

回答

2 deduper Aug 23 2020 at 06:40

…同期がない場合、SkipListはどのように並行しますか?…

TL; DRは-ConcurrentSkipListSet並行して、保持されている要素は、によって同時にに書き込むことができないので、同時に実行するスレッド。使用せずに同時実行を実現しsynchronized、ロックします。


ロングバージョン

並行コレクションのコンテキストでの並行性は、必ずしもそれらのクラスがすべてモニター(別名、synchronizedキーワード)を使用してスレッドセーフを実装することを意味するわけではありません。

まず、スレッドセーフとは、基本的に、2つ以上の競合するスレッドがアプリケーションの共有状態を変更しないようにすることです。次に、スレッドセーフを実現する以外に、いくつかの方法(パフォーマンスが高い)があることに気付きますsynchronized

そもそも状態を変更できない(不変であること)ことを確認することは、スレッドセーフを取得するための簡単ですが非常に効果的な方法の1つです。

また、スレッドセーフの責任を別のスレッドセーフクラスに委任することで、クラスをスレッドセーフにすることができます。

ConcurrentSkipListSetJavadocに記載されているように、「挿入、削除、更新、およびアクセス操作は複数のスレッドによって同時に安全に実行される」ため、同時と見なされます。

スレッドセーフの責任をスレッドセーフクラスに委任するため、並行性が実現されます。すなわち:。ConcurrentSkipListMap

ConcurrentSkipListSetであるため、スレッドセーフConcurrentSkipListMapです。またConcurrentSkipListMap、AbstractMap.SimpleImmutableEntry内部で使用することにより、状態が不変であるため、現在実行中のスレッドによって状態(キーと値)が変更されないことが保証されるため、スレッドセーフです。

上でリンクしたソースコードのいくつかの場所でConcurrentSkipListSet委任を見ることができますConcurrentSkipListMapスレッドセーフの委任について詳しく知りたい場合は、第4章「オブジェクトの作成、Java同時実行の実際」を読むことをお勧めします。

...何の問題それは私を助けることができます

これを使用すると、スレッドセーフが解放されます。を使用するよりもはるかにパフォーマンスが高く、足を撃つリスクがはるかに少ない種類ですsynchronized

…イテレータ間のこの違い以外に、なぜそれを使用する必要があるのですか?「「

アプリケーションの状態は、いくつかのコレクションに格納する必要があり、そのコレクションがアクセスできるようになります場合における任意の方法で、その後使用して、同時実行スレッドにConcurrentSkipListSetあなたが持っていることをスレッドセーフなオプションです。