2011-06-22 64 views
13

ConcurrentBagでは、複数のスレッドがバッグにアイテムを追加したり、バッグからアイテムを削除したりすることができます。スレッドがアイテムをバッグに追加してから、同じアイテムをすぐに取り出してしまう可能性があります。それは、ConcurrentBagが順序付けされていないと言いますが、どのように順序付けられていませんか?単一のスレッドでは、バッグはスタックのように動作します。順序付けられていないということは「リンクされたリストが好きではない」という意味ですか?ConcurrentBag <T>の実際の用途は何ですか?

ConcurrentBagの実際の使用は何ですか?

+5

を見ていましたか?定義された注文があるか、そうでない注文があります。エルヴィスはどう死んだの? –

+0

保存された要素の順序付けは、クライアントのビジネスのいずれにもなりません。したがって、APIの観点からは、「順序付けられていない」は常に(GetEnumeratorメソッドからの)列挙の順序を参照します。 –

+3

「注文されていない」とは、注文に関する保証がないことを意味します。現在の実装の振る舞いは、同じスレッドが追加および削除されているときにスタックのように動作し、あるスレッドが別のスレッドのコレクションから取得するときのように動作するように見えます。しかし、私はその行動には期待していません。詳細はhttp://www.informit.com/guides/content.aspx?g=dotnet&seqNum=842を参照してください。 'ConcurrentBag'は、順序が重要でない場合、スレッドがプロデューサとコンシューマの両方になることができる場合、' ConcurrentQueue'よりも優れたパフォーマンスを提供します。 –

答えて

3

バッグはインスタンスカウントを追跡するのに本当に便利です。たとえば、Webリクエストを処理しているホストのレコードを保持したい場合は、リクエストのサービスを開始するときにIPをバッグに追加し、完了したらそのIPを削除できます。

バッグを使用すると、現在サービスしているIPを一目で把握できます。また、特定のIPアドレスをサービスしているかどうかを素早く問い合わせることもできます。

バッグの代わりにセットを使用すると、同じIPアドレスから同時に複数のリクエストがあると、あなたの記録保持が壊れてしまいます。

+7

自分のIPをバッグに追加して、完了したらIPアドレスを削除します。バッグから特定のアイテムを取り除くにはどうすればいいですか? –

+2

@ダスティン:良い質問です。私は[ConcurrentHashMultiset'](https://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/ConcurrentHashMultiset.html)(Javaの 'ConcurrentBag' )私は答えを書いていましたが、これは 'remove'メソッドを持っています。 .NETの 'ConcurrentBag'クラスが何のために良いのか分かりません。 :-P –

+2

あなたの答えに基づいて、私は自分自身に適用できる現実のシナリオを考え出すことができました。 –

1

ランダムなアクセスや保証された注文を必要とせず、その内容を把握するだけで十分です。処理する項目を追加するスレッドと、処理するために項目を削除するスレッドがある場合、FIFO順に処理されても構わない場合は、並行バッグがうまく機能します。

+3

現実のシナリオ... –

1

@Chris Jester-Youngのおかげで、実際には私が取り組んでいるプロジェクトに適用される良い、現実のシナリオを考え出しました。

検索 - プロセス - ストア

を探す - 1 & 2は、データを検索したりこすりするように設定されているスレッド(ファイルシステム、ウェブ、など)。これらの結果はConcurrentBag1に格納されます。

プロセスから3 & 4 ConcurrentBag1、クリーン/変換/プロセスデータの取り出し、次いでConcurrentBag2に結果を格納するように設定されているスレッド。

ストア - スレッド5は、ConcurrentBag2の結果を収集し、結果をSQLに格納するように設定されています。

+0

説明から、これは、 'ConcurrentBag'クラスではなく、階層化されたキュー(おそらく' ConcurrentQueue'または 'BlockingCollection'インスタンス)を使って実装する方が良いように思えます。クラスの使用にはかなりの重複があるように見えますが、間違いかもしれません。 –

12

ConcurrentBagは順序付けがないため、ConcurrentStack/Queueよりもパフォーマンス上の利点があります。ローカルスレッドストレージとしてMicrosoftによって実装されています。したがって、アイテムを追加するすべてのスレッドは、それ自身のスペース内でこれを行います。アイテムを取得するときには、それらはローカルストレージから取得されます。それが空のときだけ、スレッドはアイテムを別のスレッドストレージから盗みます。そのため、単純なリストの代わりに、ConcurrentBagはアイテムの分散リストです。ほとんどロックフリーであり、高い同時実行性でより優れた拡張性を持つ必要があります。

は、残念ながら、.NET 4.0に(4.5で修正された)パフォーマンスの問題は、あなたが「それがどのように順序付けられていないです」とは何を意味しています http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

関連する問題