0

散文で次のように説明できる高性能環境で問題が発生しました。

64個のリソースを持つFPGAカードを呼び出す外部JavaAPIがあります。アプリケーション内の数百のスレッド間でこれらのリソースのサブセットを安全に共有するためのメカニズムが必要です。各リソースはスレッドセーフではないと見なす必要があります。

そのため、update()メソッドを持つResourcePoolが必要です。このメソッドは、resource.update()を呼び出します。

これはかなり一般的なイディオムだと思いますが、Javaの概念に頭を合わせるのに苦労しています。1つのResourcePoolに4つのリソースがあると言いたいです。それぞれが独自のスレッドに住んでいると推測する必要があります(したがって、スレッドプールが必要になります)。

4つのリソースがすべて使用されているときにエラーをログに記録して続行できるようにするには、これをどのように実装しますか?

これが理にかなっていることを願っています!

4

4 に答える 4

3

各リソースを表すオブジェクトをLinkedBlockingQueueに配置します。

リソースを取得するには、必要に応じて、poll()、remove()、またはtake()を実行できます。

リソースを返すには、リソースを追加できます。

于 2012-10-10T15:43:10.303 に答える
2

@Peterによって提案されているように、LinkedBlockingQueueを使用してリソースをプールすることは、各スレッドが1つのリソースのみを必要とする限り問題ありません。多数のスレッドが複数のスレッドを必要とする場合、単純なケースでは、多数のスレッドがいくつかのリソースを取得したが、それらのいずれかが続行するには不十分である場合に問題が発生する可能性があります-デッドロック。

1つのロックで保護された2つのキューを使用できます。リソースインスタンスの1つの「プール」キュー、リソースの取得を待機しているスレッドインスタンスの1つの「待機」キュー。スレッドクラスのメソッドは、現在待機しているリソースの数を返します。

リソースを必要とするスレッドはすべてロックを取得し、最初にプールキュー数をチェックします。十分なリソースがある場合は、リソースをデキューしてロックを終了します。十分な数がない場合は、待機キューに入れられ、ロックを終了して待機します。

リソースを解放できるスレッドはすべて、ロックを取得します。待機キューが空の場合、リソースをプールに解放し、ロックを解放して終了します。待機キューが空でない場合は、待機キューが繰り返され、解放されるのを待機しているリソースとプールに残っているリソースの合計で準備できる待機スレッドのセットが構築されます。次に、ある種のアルゴリズムを適用して、待機中のスレッドを準備できるかどうかを決定します。存在しない場合は、リソースをプールに解放してロックを終了します。存在する場合は、それらのスレッドにリソースをロードし、通知し、ロックを解除して終了します。

于 2012-10-10T16:14:23.723 に答える
1

BlockingQueueの場合、生産者/消費者パターンにとって非常に便利です。userdがこのリソースの後に更新または追加する必要がありますが、リソースの初期化のパフォーマンスが低い可能性があります。そして、それはキューをブロックしています。プールが空または満杯のときに情報を処理したい場合は、キューで問題ありません。

ロックの場合、これらのリソースが初期化され、後で変更されない場合は、これらのリソースにロックを追加することをお勧めします。

これは私の意見です。

于 2012-10-11T03:36:37.977 に答える
0

基本的に、有限数の汎用リソースとして扱うことができるものがあるため、任意の汎用リソースプーリングライブラリを適用できます。グーグルは最初のヒットとしてpool4jを返しました、これはあなたが必要とするすべてであるかもしれません。に基づいていjava.util.Stackます。または、独自のソリューションを展開することもできます。

于 2012-10-11T13:24:45.610 に答える