1

私がこのコードを持っているとしましょう:

public HttpResponse myFunction(...) {
    final HttpResponse resp;
    OnResponseCallback myCallback = new OnResponseCallback() {
        public void onResponseReceived(HttpResponse response) {
            resp = response;
        }
    };
    // launch operation, result will be returned to myCallback.onResponseReceived()
    // wait on a CountDownLatch until operation is finished
    return resp;
}

明らかに、onResponseReceivedからrespに値を割り当てることはできません。これは最終変数であるためですが、最終変数でない場合、onResponseReceivedはそれを認識できませんでした。次に、onResponseReceivedからrespに値を割り当てるにはどうすればよいですか?

私が考えたのは、respオブジェクトを囲むためのラッパークラスを作成することです。最終オブジェクトはこのラッパークラスのインスタンスであり、最終クラス(最終ではない)内のオブジェクトで動作するrespに値を割り当てることができます。

コードは次のようになります。

class ResponseWrapper {
    HttpResponse resp = null;
}

public HttpResponse myFunction(...) {
    final ResponseWrapper respWrap = new ResponseWrapper();
    OnResponseCallback myCallback = new OnResponseCallback() {
        public void onResponseReceived(HttpResponse response) {
            respWrap.resp = response;
        }
    };
    // launch operation, result will be returned to myCallback.onResponseReceived()
    // wait on a CountDownLatch until operation is finished
    return respWrap.resp;
}

このソリューションについてどう思いますか?

4

5 に答える 5

7

java.util.concurrent.atomic.AtomicReference

標準的な方法は、設定して取得できる最終的なAtomicReferenceを使用することです。これにより、スレッドセーフの利点も追加されます:)おっしゃるように、CountDownLatchは完了を待つのに役立ちます。

于 2012-12-12T17:28:06.017 に答える
4

あなたのソリューションは他のソリューションと同じように有効です。他の一般的な選択肢には、1要素配列が含まれます

final HttpResponse[] resp = new Response[1];
// In the callback
resp[0] = response;
// After the operation
return resp[0];

および汎用ラッパー

public class Ref<T> {
  public T value;
}

final Ref<HttpResponse> resp;
// In the callback
resp.value = response;
// After the operation
return resp.value;
于 2012-12-12T17:29:52.680 に答える
1

SynchronousQueue(例外処理は省略)を使用して、ハンドバックと待機を1つに組み合わせることができます。

public HttpResponse myFunction(...) {
    final Queue<HttpResponse> resp = new SynchronousQueue<HttpResponse>();
    OnResponseCallback myCallback = new OnResponseCallback() {
        public void onResponseReceived(HttpResponse response) {
            resp.put(response);
        }
    };
    return resp.take();
}
于 2012-12-12T17:36:19.787 に答える
0

これは明らかにマルチスレッドであり、独自のラッパーを作成する必要がないため、私が行う変更はAtomicReferenceを使用することです。そうでなければ、私には合理的なようです。

于 2012-12-12T17:29:26.493 に答える
0

可変で最終的なものにすることができます;)最も簡単なアプローチはna配列を使用することですが、AtomicReferenceも使用できます。

public HttpResponse myFunction(...) {
    final HttpResponse[] resp = { null };
    OnResponseCallback myCallback = new OnResponseCallback() {
        public void onResponseReceived(HttpResponse response) {
            resp[0] = response;
        }
    };
    // launch operation, result will be returned to myCallback.onResponseReceived()
    // wait on a CountDownLatch as soon as operation is finished
    return resp[0];
}

また

public HttpResponse myFunction(...) {
    final AtomicReference<HttpResponse> resp = new AtomicReference<HttpResponse>();
    OnResponseCallback myCallback = new OnResponseCallback() {
        public void onResponseReceived(HttpResponse response) {
            resp.set(response);
        }
    };
    // launch operation, result will be returned to myCallback.onResponseReceived()
    // wait on a CountDownLatch as soon as operation is finished
    return resp.get();
}
于 2012-12-12T17:30:47.350 に答える