2

私のプログラムでは、基本的にパブリッシャーに接続してデータを取得しようとしています。基本的な機能はこれらの手順にあります

  1. ユーザー名とパスワードなどを使用してパブリッシャーに接続します
  2. データのリクエストを行います。メソッドの終了
  3. パブリッシャーの API がメソッドへのコールバックを提供するonDataUpdate(Object theUpdate)

そこから、データを印刷したり、データベースに書き込んだり、必要なことを行うことができます。それはすべてうまくいきます。

私の問題は、呼び出し元のプログラムがデータを要求するとすぐにデータを受信できるように機能をラップしたいということです。つまり、公開されたメソッドを次のように見せたい

public Object getData() {
    subscribeForData();
    // somehow wait
    return theUpdate;    
}

どうすればこれを実現できますか? 更新を受信したときにスレッドを使用して待機/通知する方法はありますか? 私はstackoverflowとマルチスレッドプログラミングの初心者なので、ヘルプとサンプルコードをいただければ幸いです!! 前もって感謝します。

4

5 に答える 5

1

この場合、私はCountDownLatchlathchを使用することを好みます。ここでは、パブリッシャをサブスクライブするとすぐにカウント 1 で初期化し、コールバックを取得するとを呼び出しawait(ます。latchcountdownlatch

于 2012-07-03T18:16:37.283 に答える
0

私はあなたの質問について完全に確信しているわけではありませんが、試してみます-役に立てば幸いです:)

この目的のためにJavaでブロッキングキューを使用できます(プロデューサーコンシューマーメッセージ)-コールバックが呼び出されたときにキューに書き込む場合-別のスレッドから、キューから読み取ることができます。ブロッキング キューはスレッド セーフです (ただし、要件に合わない場合があります)。

コレクションに書き込むスレッドが 1 つしかなく、おそらく複数のリーダー (またはリーダーのみ) がある場合は、読み取り書き込みロックを調べることもできます。

また、オブザーバー パターンを調べることもできます - 参照用: http://www.vogella.com/articles/DesignPatternObserver/article.html

どちらも機能しない場合は、ZeroMQ/ActiveMQ などの VM 内メッセージング サーバーや、おそらく Redis/HazelCast などのキュー/トピックの使用を検討できます。

それが役立つことを願って、幸運を祈ります

于 2012-07-03T18:19:50.233 に答える
0

非同期呼び出しを同期呼び出しに変換するのは興味深い演習です。インタビューでよく使用します (逆に、同期呼び出しを非同期でラップします)。

したがって、requestDataすぐに返されるメソッドがあり、それ (または他の何か) は後で別のスレッドonDataUpdateで呼び出されます。呼び出し元がコールバックを使用する必要がなく、代わりにデータが利用可能になるまでブロックして呼び出し元に返す新しいメソッドを作成したいとします。requestDataSynchronous

だからあなたがする必要があるのrequestDataSynchronousは:

  1. 電話requestData
  2. が呼び出されるまで待機onDataUpdateします(別のスレッドで)
  3. onDataUpdate受信したデータを取得する
  4. 呼び出し元に返す

上記のうち、#2 と #3 は、スレッド間通信の何らかのモードで実行する必要があります。wait/を使用できますが、 BlockingQueuenotifiyを使用する方がはるかに簡単な場合があります。データが利用可能になると書き込み、そこから読み取り、書き込みが行われるまで読み取りをブロックします。onDataUpdaterequestDataSynchronousonDataUpdate

を使用ExecutorServiceするとさらに簡単になるかもしれませんが、何が起こっているのかを知っておくと便利です。

于 2012-07-03T18:35:55.280 に答える
0

SynchronousQueue を使用します。getData で作成し、コールバック メソッドで put() を呼び出し、getData() の最後で元のスレッドで take() を呼び出します。

于 2012-07-03T18:12:06.557 に答える
0

CompletionService、特にExecutorCompletionServiceを確認してください。本Java Concurrency in Practiceには、Web ページのローダー/レンダラーの良い例があります。

于 2012-07-03T18:13:22.847 に答える