[解決済み] Javaにおけるスレッドセーフセットの種類
質問
JavaでスレッドセーフなSetsを生成するには、様々な実装や方法があるようです。 いくつかの例を挙げます。
2) Collections.synchronizedSet(セットセット)
4) Collections.newSetFromMap(新しいConcurrentHashMap())
5) (4)と同様の方法で生成されたその他のセット
これらの例は 同時進行パターン。Java 6 の並行セット実装
どなたか、これらの例などの違いやメリット、デメリットを簡単に説明していただけませんか?私は、Java Std Docsからすべてを理解し、まっすぐに保つのに苦労しています。
どのように解決するのですか?
-
その
CopyOnWriteArraySet
基本的には配列の中に要素のリストがあり、リストを変更するときに配列をコピーします。このとき実行中の反復処理や他のアクセスは古い配列で継続されるので、読み手と書き手の間で同期をとる必要はありません(ただし、書き込み自体は同期が必要です)。通常高速なセット操作(特にcontains()
というのも、配列は線形時間で検索されるからです。これは、頻繁に読み込まれ、めったに変更されない、本当に小さなセットにのみ使用します。(Swingのリスナーセットがその例ですが、これらは本当のセットではないので、いずれにせよEDTからしか使うべきではありません)。
-
Collections.synchronizedSet
は、元のセットの各メソッドを単にsynchronized-blockで囲むだけです。元のセットに直接アクセスするべきではありません。これは、セットの2つのメソッドを同時に実行できないことを意味します(一方は他方が終了するまでブロックされます)。これはスレッドセーフですが、複数のスレッドがセットを使用している場合は同時実行ができません。イテレータを使用する場合、イテレータ呼び出しの間にセットを変更するときに ConcurrentModificationExceptions を回避するために、通常は外部で同期を取る必要があります。 性能は元のセットの性能と同じになります(ただし、同期のオーバーヘッドがあり、同時に使用するとブロックされます)。同時実行性が低く、すべての変更が他のスレッドからすぐに見えることを確認したい場合に使用します。
-
ConcurrentSkipListSet
は、同時進行のSortedSet
の実装で、ほとんどの基本操作はO(log n)で可能です。追加/削除と読み込み/反復を同時に行うことができ、反復はイテレータが作成されてからの変更について伝えることもできますし、伝えないこともできます。一括操作は単純に複数の単一呼び出しであり、アトミックに行われるわけではありません - 他のスレッドはその一部しか観察できないかもしれません。明らかに、これは要素に何らかの総体的な秩序がある場合にのみ使用することができます。 これは、あまり大きくないセットで、高い同時実行性が必要な場合に理想的な候補に見えます(O(log n)のため)。
-
については
ConcurrentHashMap
(およびそこから派生するセット): ここで最も基本的なオプションは、(平均して、高速で優れたhashCode()
)で、HashMap/HashSetと同様にO(1) (ただし、多くのキーが同じハッシュコードを持つ場合はO(n)に退化する可能性がある)で実現できる。書き込みの並行性には制限があり(テーブルはパーティション化されており、書き込みアクセスは必要なパーティションで同期される)、読み込みアクセスは自身と書き込みスレッドで完全に同時進行する(ただし、現在書き込まれている変更の結果はまだ見ていないかもしれない)。イテレータは、それが作成されてからの変更を見ることも見ないこともあり、バルク操作はアトミックではありません。 リサイズには時間がかかる(HashMap/HashSetと同様)ので、作成時に必要なサイズを推定してこれを避けるようにする必要があります(3/4がいっぱいになるとリサイズされるので、その約1/3を使用することになります)。大きなセットと優れた(そして高速な)ハッシュ関数があり、マップを作成する前にセットのサイズと必要な同時実行性を見積もることができる場合に使用します。
-
他の並列マップの実装はありますか?
関連
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] Javaにおける "implements Runnable "と "extends Thread "の違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java Error スレッド "AWT-EventQueue-0" で例外発生 java.lang.
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
エラーが報告されました。リソースの読み込みに失敗しました:サーバーは500(内部サーバーエラー)のステータスで応答しました。
-
JavaMailのメール送信が失敗するケースとその説明の分析
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
javaでクラスを作成すると、enclosing classでないように見える
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
Error: java.lang.NoClassDefFoundError: クラス XXXX を初期化できませんでした
-
HttpClientがGZIP形式でない場合の対処法
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について