問題タブ [concurrenthashmap]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 並行ハッシュマップを正しく使用するには?
たとえば、多くの読み取り操作といくつかの書き込み操作があり、マップに配置されるオブジェクトは非常に「重い」-そのようなオブジェクトの初期化には多くのメモリ/時間がかかるなど.
並行ハッシュマップの高いパフォーマンスを利用し、キャッシュされたオブジェクトの不要な初期化のコストを最小限に抑えるには、どのようにコーディングすればよいでしょうか。
サンプル コード スニペットは大歓迎です。ありがとう!
java - ConcurrentHashMapの実装と制限
私には達成すべき非常に大きなプロジェクトがあり、いくつかの行き詰まりに直面しています。ここの素晴らしいコミュニティに何か提案があるかどうかを見たかったのです。
私は大規模なデータセットを持っており、ソーシャルグラフを作成しようとしています。データには、Short値への座標の950万を超えるマッピングが含まれています。ConcurrentHashMapのキー値には、文字列を使用しています。これは、間に「、」を連結した座標です。
基本的に、ユーザー間で共通するグループの数を見つけています。GroupIDをAvatarIDのVectorにマップする非常に簡単に作成できる初期ハッシュマップがあります。この部分は正常に動作します。次に、独自のGroupIDのセットと処理(各groupIDのユーザー間のカウントに+1を追加)を担当する12のスレッドがあり、すべてのアクセスはConcurrentHashMapから行われます。
約8000のグループが処理された後、アクセスに関する問題が発生します。一度に1つのスレッドだけがアクティブになっているように見えますが、これが巨大なサイズによるものなのか、それとも別の要因によるものなのかはわかりません。合計で(そしてタイムリーに)処理する必要がある300,000のグループがあるため、これは問題です。
これをどのように実装するか、および使用できるショートカットについてアドバイスはありますか?値が存在する場合(作成しない場合)に座標を読み取り、値に1を追加して書き戻す必要があるため、読み取りと書き込みも同様に重要であると考えています。
必要に応じてコードを提供したいと思っていますが、どの部分がディスカッションに関連するかはまだわかりません。
お時間をいただきありがとうございます、-mojavestorm
詳細な説明:
2つの実装とその制限:
1)キーとしてGroupIDとuserIDのVectorを含むHashMap(Integer、Vector(Integer))preMapがあります。スレッドはGroupIDを相互に分割し、返された各Vector(Integer)を使用して、各スレッドは座標に従って短い値を格納します(UserIDxとUserIDyは(短い)nグループに属します)。各スレッドは独自のthreadMapを所有しています。座標は長い値にマップされます。各スレッドが完了すると、各threadMapの対応するキーの値がcombinedMapの同じキーに追加されます。これにより、システム全体でUserIDxとUserIDyが一緒に属するグループの数が示されます。
この実装の問題は、スレッド間に高いオーバーラップがあるため、過度の短い値が作成されることです。たとえば、ユーザー1とユーザー2は一緒にさまざまなグループに属しています。スレッドAとスレッドBは、ユーザー1とユーザー2が属するグループを含む、独自の範囲のグループを担当します。したがって、スレッドAとスレッドBはどちらも、スレッドマップのコピーに座標(1、2)と短い値。過度のオーバーラップが発生した場合、メモリ要件が未解決になる可能性があります。私の場合、Javaに割り当てた46GBのRAMはすべて使い果たされ、すぐに使い果たされてしまいます。
2)この実装で同じpreMapを使用して、各スレッドには、担当するユーザー座標の範囲が与えられます。各スレッドは実行され、各スレッドを取得してpreMapを反復処理し、各groupIDをチェックして、UserIDxとUserIDyがpreMapから返されたベクトルに属しているかどうかを確認します。この実装により、threadMap間で発生するオーバーラップが排除されます。
これの問題は時間です。現在、このプログラムは1400年という驚異的な速度で実行されています。メモリは約4GBから15GBの揺れを使用しましたが、「低い」ままのようです。制限内に収まるかどうかは完全にはわかりませんが、そうなると思います。私には明らかな改善はありません。
うまくいけば、これらの説明が明確であり、私の問題への洞察を与えるのに役立つでしょう。ありがとう。
java - 同時ハッシュマップを使用してスレッドプールのメモリ使用量を削減しますか?
長いSQLクエリを実行し、処理された結果をHashMapに格納するプログラムを使用しています。現在、20〜200の各クエリの実行時間が遅いことを回避するために、固定スレッドプールとカスタム呼び出し可能オブジェクトを使用して検索を行っています。その結果、各呼び出し可能オブジェクトはデータのローカルコピーを作成し、それをメインプログラムに戻してレポートに含めます。
以前は問題なく実行されていた100個のクエリレポートにより、メモリが不足していることに気付きました。私の推測では、これらの呼び出し可能オブジェクトはデータの独自のコピーを作成しているため、それらを別の大きなHashMapに結合すると、メモリ使用量が2倍になります。呼び出し可能オブジェクトのテーブルのスコープを縮小することで、ガベージコレクターを実行するように誘導できることはわかっていますが、回避できるのであれば、そのレベルの再構築は実際にはやりたいことではありません。
呼び出し可能オブジェクトを、データを格納する代わりに同時HashMapに書き込む実行可能オブジェクトに置き換えることで、メモリ使用量を改善できますか?それとも、ここで他の問題があるように聞こえますか?
c++ - TBB 同時ハッシュ マップ
tbb の同時ハッシュ マップを実装して、そのパフォーマンスを他の一連の同時ハッシュ テーブルと比較しています。
しかし、それから得られるパフォーマンスは恐ろしいものです。他の同時ハッシュテーブルと比較してそれほど遅いとは信じられません
これが私の実装です:
私の実装に何か問題が見られるか、パフォーマンスが低下する理由を知っている人はいますか? シングル スレッド環境で 200,000 要素を挿入するには、30 分以上かかります。概観すると、他のほぼすべてのテーブルがこのテストを 5 分未満で実行します。
ここに私のビルドコードがあります:
更新: ハッシュ テーブルを 100,000 ではなく 1000 に事前設定するようにテスト コードを調整しました。再度実行すると、tbb は 92 オペレーション/秒を実行しますが、別の実装では 89431 オペレーション/秒を実行します。(64スレッド環境)…なんか言い方がおかしい…。
追加情報: コンピューターは、6 GB の RAM と 6 コアを搭載した HP Z600 ワークステーションです。
相互配置に注意してください: http://software.intel.com/en-us/forums/showthread.php?t=86119
java - @Singleton キャッシュの実装
キャッシュの実装が正しいかどうか疑問に思っており、フィードバックをいただければ幸いです。リソースには、いくつかの文字列 (クライアント アドレス) 値が割り当てられています。
addEntityRegistration() メソッドを同期する必要がありますか? または、このユースケースに対するより良いアプローチはありますか?
前もって感謝します、m
java - ConcurrentHashMap foreach ループの問題
ユーザーと呼ばれる並行ハッシュマップがあります。IDではない整数キーを持つユーザーオブジェクトがあります。特定のIDを持つユーザーを見つけたい。したがって、hashmap のすべての要素をチェックし、存在する場合はユーザー オブジェクトを返します。これが私のコードです:
ただし、u.getId() と id が同じであっても、ログに「一致」が表示されません。
213件マッチしましたが、以下のif文は入れられません。ここに私のログがあります:
あなたはそれについてどう思いますか?
java - オブジェクトを ConcurrentHashMap に再配置すると、「前に発生する」メモリ関係が発生しますか?
ConcurrentHashMap の形式のオブジェクト ストアを持つ既存のコードを使用しています。マップ内には、複数のスレッドで使用される変更可能なオブジェクトが格納されています。設計上、2 つのスレッドが同時にオブジェクトを変更しようとすることはありません。私の懸念は、スレッド間の変更の可視性に関するものです。
現在、オブジェクトのコードは「セッター」で同期されています (オブジェクト自体によって保護されています)。「ゲッター」には同期がなく、メンバーは揮発性ではありません。これは、私にとって、可視性が保証されていないことを意味します。ただし、オブジェクトが変更されると、マップに再配置put()
されます (同じキーでメソッドが再度呼び出されます)。これは、別のスレッドがマップからオブジェクトをプルすると、変更が表示されるということですか?
これについては、stackoverflow、JCIP、および java.util.concurrent のパッケージの説明で調査しました。私は基本的に自分自身を混乱させたと思います...しかし、この質問をするようになった最後のストローは、パッケージの説明からのものでした。
オブジェクトを並行コレクションに配置する前のスレッド内のアクションは、別のスレッド内のコレクションからのその要素へのアクセスまたは削除に続くアクションの前に発生します。
私の質問に関連して、「アクション」には、re-put() の前にマップに格納されたオブジェクトへの変更が含まれますか? これらすべてがスレッド間の可視性につながる場合、これは効率的なアプローチですか? 私はスレッドに比較的慣れていないので、コメントをいただければ幸いです。
編集:
皆様、ご回答ありがとうございます!これは StackOverflow に関する私の最初の質問であり、非常に役に立ちました。
それが私の混乱を最も明確に解決したと思うので、私はptomliの答えに行かなければなりません。つまり、この場合、「前に発生」関係を確立しても、必ずしも変更の可視性に影響するわけではありません。私の「タイトルの質問」は、テキストで説明されている実際の質問に関して構成が不十分です。ptomliの答えは、私がJCIPで読んだものと一致するようになりました。オブジェクトをマップに再配置しても、挿入されたオブジェクトのメンバーを変更するためのこの共通ロックは提供されません。
変更に関するすべてのヒント (不変オブジェクトなど) に感謝し、心から同意します。しかし、この場合、前述したように、慎重にスレッドを処理するため、同時変更はありません。1 つのスレッドがオブジェクトを変更し、後で別のスレッドがそのオブジェクトを読み取ります (CHM がオブジェクト コンベアです)。私が提供した状況を考えると、後で実行するスレッドが最初から変更を確認できるようにするには、CHM が不十分だと思います。しかし、タイトルの質問に正解した方も多いと思います。
java - ConcurrentHashMap のノンブロッキング読み取りとメモリの可視性の問題
ConcurrentHashMap
in Java は、更新と同時に続行する読み取りを提供します。これのトレードオフは、読み取りの結果が、読み取りが開始されたときに最後に完了した更新のみを反映するように制限されているため、要素の最新の状態を反映するように指定されていないことです。
ただし、AFAIK Java Memory Model では、読み取りスレッドと書き込みスレッド間の何らかの形式の同期がないと、書き込みスレッドの更新が、任意の時間が経過しても読み取りスレッドに表示されない場合があります。
読み取りスレッドが書き込みスレッドでブロックされない場合、最後に完了した更新の可視性を読み取りスレッドが利用できることを保証する根拠は何ですか?
実行中のコンペア アンド スワップ アルゴリズムの行で何かを考えることができましたが、そのライブラリのソース コードでそれを確認することはできませんでした。
java - Java tomcat 特定の http スレッドのみをキューに入れる方法は?
Tomcat Web サーバーにデプロイされたステートレス Java アプリケーションがあります。データの性質上、常にすべての http スレッドが異なるキーを処理する必要があります (つまり、すべてのスレッドが異なるキーを処理する必要があります)。
したがって、リクエストのキーが現在進行中の場合に http ポストをキューに入れるモジュールを作成しました (この前の http ポストによって)。同じキーを持つ以前の http 投稿が処理を完了した場合にのみ、現在の http 投稿の処理を続行します。
進行中の同じキーを持つ以前のリクエストがあるかどうかをテストするために、concurrenthashmap を使用した単純な while ループを作成しました。パフォーマンスは標準以下で、予期しない動作があります。これはコード スニペットです。
各 http 投稿の最後に、finally ブロックに次のように入力しました。しかし、私の最悪の悪夢では、サーバー ログから、別の http ポスト スレッドである queueKey を削除する前に、なんとか上記の while ループから抜け出し、処理を続行していることに気付きました。
httpスレッドを「キューに入れる」ために上記のコードで間違ったことはありますか?
また、これをより良く行う方法についてのアイデアも大歓迎です。
java - ConcurrentNavigableMap、一貫性の低い反復子の解釈
ConcurrentNavigableMapのJavaDoc では、次の点について少し混乱しています。
ビューのイテレータは、ConcurrentModificationException を決してスローしない「弱い一貫性のある」イテレータであり、イテレータの構築時に存在していた要素をトラバースすることを保証し、構築後の変更を反映する場合があります (ただし保証はされません)。
ConcurrentSkipListMap のようなインターフェースの実装では、言葉遣いは同じようです。
これはどういう意味ですか、矛盾しているように見えます-構築時に存在する要素をトラバースすることを保証できるか、または構築後の変更を反映する可能性がありますか??
更新: 基本的に、ConcurrentSkipListMap のような ConcurrentNavigableMaps でイテレータを作成すると、マップの「スナップショット」ビューが作成されるかどうかを知りたいです。