1

ResponseWebサービスへの応答後を表すためのオブジェクトがあります。このコードを考えると:

Response resp1= Server.request(a);
Response resp2= Server.request(b);
Response resp3= Server.request(c);
if (resp1.isOk() && resp2.isOk() && resp3.isOk()){
    // Do stuff
}

サーバーは少し遅いので、3つのスレッドで請願を並列化したいです。しかし、メインスレッドで結果を待機し、3つの応答を取得する方法がわかりません。

4

3 に答える 3

1

スレッドベースのアプローチがいくつかあります。

  • 1つ目は、ブロッキング呼び出しを公開することです。

    resp1.waitFoCompletion();

  • 2つ目は、ポーリングメカニズムを提供することです(あまり良くありません)

    while(resp1.isCompleted())

  • 3つ目は、メインクラスが実装できるコールバックを提供することです。

    interface Callback() { void onCompletion(Result result); }

ただし、重要な問題は、たとえば、利用できるのに、なぜ自分でこれを行うのかということExecutorsです。

于 2012-08-30T15:38:03.413 に答える
1

できません。3つの別々のスレッドをスピンオフしてから、プライマリスレッドに3つのスレッドをポーリングさせ、それらが終了していない場合はしばらく待つ必要があります。どのサービスが遅いかがわかっている場合は、他のスレッド用に別々のスレッドを起動した後、プライマリスレッドにそのスレッドを呼び出させることができますが、それでも、他の1つが異常な状況で時間がかかる場合に対処する必要があります。

ただし、いくつかのコメントがあります。これが実際に読み込みの問題である場合、余分なスレッドをスピンオフしてもおそらく役に立たず、実際に問題が発生する可能性があります。このアプローチは、複数のサービスが実際に遅い場合にのみ役立ちます。これは、この1回の呼び出しに対して多くのことを行う必要があるためです(負荷がかかっているためではありません)。さらに、それらは別々のハードウェア上にある必要があります。とにかく、これらが実際にハードウェアを共有している場合は、それぞれがマルチスレッドの方法で他のハードウェアの速度を低下させるため、並列で実行されているように見えるだけです。

最後に、新しいスレッドを意地悪にスピンオフするべきではありません。それらは比較的高価な消耗品です。スレッドプールはN個を超えないようにする必要があります。また、ブラックホールに陥らないように十分に注意する必要があります。したがって、すべてのスレッドにタイムアウトが必要であり、プロセスは常にクリーンアップして、考えられるすべてのエラーの場合にスレッドをプールに戻す必要があります。

編集:前のポスターはエグゼキューターの使用を提案しており、コールバックについても言及しています。彼のリンクをたどると、Executorのデフォルトの実装は別のスレッドをスピンオフせず、完了を待つだけなので、並列処理は行われません。ただし、executor-with-a-callbackパターンは、スレッドプールを実装し、前述のポーリングおよび待機メカニズムを統合するための優れたパターンです。エグゼキュータはスレッドプールとタスクの起動を処理してから、コールバックを呼び出します。プライマリスレッドはタスクを使用してエグゼキュータを作成し、コールバックはプライマリスレッドのオブジェクトにフラグを設定するものにすぎません。これで、プライマリスレッドには、設定されているすべてのフラグを探して待機するループが必要です。

于 2012-08-30T15:42:15.957 に答える
1

3 つのスレッドで呼び出しを開始し、その終了を待つために、次のようなことができると思います。

private Response resp1, resp2, resp3;

protected void doRequests() {
    Thread thread1 = new Thread() {
        public void run() {
            resp1= Server.request(a);           
        }
    };
    Thread thread2 = new Thread() {
        public void run() {
            resp1= Server.request(a);           
        }
    };
    Thread thread3 = new Thread() {
        public void run() {
            resp1= Server.request(a);           
        }
    };

    thread1.start();
    thread2.start();
    thread3.start();

    try { thread1.join(); } catch(InterruptedException e) { }
    try { thread2.join(); } catch(InterruptedException e) { }
    try { thread3.join(); } catch(InterruptedException e) { }
}
于 2012-08-30T15:45:48.610 に答える