4

ブロックしている特定の API を使用する Java プロジェクトに取り組んでいます。

結果を待っている間にブロックする必要がないように、非同期プログラミングとコールバックを使用したいと思います。JavaFutureの使用を検討しましたが、それを使用できると思う唯一の方法は、get()ブロックするメソッドを呼び出すことです。私は、非同期プログラミングを行うために他の方法を使用することにもオープンです。

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

Object res = blockingAPI();
sendToClient(res);

を使うFutureとしたら、このようにします。しかし、私の理解はget()ブロッキングです。

private final int THREADS = Runtime.getRuntime().availableProcessors();
private ExecutorService executor = Executors.newFixedThreadPool(THREADS);

public void invokeApi() {
    Future<Object> future = executor.submit(new Callable<Object>() {
        public Object call() {
            return result;
        }
    });

    Object result = future.get(5, TimeUnit.SECONDS)
}

get()結果が利用可能になったときに自動的に呼び出されるコールバックによって関数が基本的に処理されるように、これを実装するにはどうすればよいでしょうか?

4

2 に答える 2

4

いくつかのオプション。

1 つは、未来を CompletableFuture にラップすることです。

public static <T> CompletableFuture<T> makeCompletableFuture(Future<T> future) {
    return CompletableFuture.supplyAsync(() -> {
        try {
            return future.get();
        } catch (InterruptedException|ExecutionException e) {
            throw new RuntimeException(e);
        }
    });
}

もう1つは Guava を使用することListenableFutureです:

ListeningExecutorService service = MoreExecutors.listeningDecorator(executor);
ListenableFuture<T> future = service.submit(callable);
Futures.addCallback(future, new FutureCallback<T>() {
    public void onSuccess(T t) {
        // ...
    }
    public void onFailure(Throwable thrown) {
        // ...
    }
});

高度に構成可能なAkka Futuresを使用することもできます。

于 2015-07-01T19:12:15.360 に答える
0

2 つの基本的なオプションがあります。

  • 定期的にプールして結果を得る:

    FutureisDone()Callable の計算結果が揃っているかどうかを確認するメソッドを API が提供しています。これはブール値を返すノンブロッキング メソッドです。結果が準備できている場合は true、それ以外の場合は false です。

  • 結果にサブスクライブし、結果の準備ができているという通知を待っている間に有用な作業を行います。これを実現する方法はたくさんありますが、おそらく最も簡単な方法は を使用することObserver Patternです。

あまり知られていませんが、非同期プログラミングで使用できるその他の便利なパターンは、Active objectHalf sync - half asyncです。

アクティブ オブジェクトは、クライアントがブロッキングを使用して並行オブジェクトのサービスを呼び出す方法で機能します。これらの結果を、優先順位に従って、またはその他の基準に従って処理するスケジュール メカニズムがあります。

以下の例では、クライアント サービスが Runnable にラップされる実装がありますが、代わりにサービスを Callable にラップするように簡単に変更し、Client と Active オブジェクトの間にプロキシを配置して、callable からの結果をサブスクライブすることができます。

アクティブなオブジェクト

于 2015-07-01T19:18:30.687 に答える