1. ホーム
  2. java

[解決済み] Vertx: executeBlocking() vs Future。何が違うの?

2022-02-10 16:19:03

質問

Vertxのドキュメントによると executeBlocking() メソッドは、ブロッキング API を呼び出す必要があるときに使用します。一方、VertxはFutureという概念も提供しており、基本的に同じことができる。しかし executeBlocking() メソッドは静的なものではありません。また、Futureの単純なラッパーでもなく、その 実装 は、かなり複雑であることがわかる。この2つの違いは何でしょうか?

ある長時間実行するタスクを非同期で実行したいと仮定します。この2つの方法に違いはあるのでしょうか?

方法1:

doTheJob() {
    Future<Void> future = Future.future();
    executeLongRunningBlockingOperation();
    future.complete();
    return future;
}

doTheJob().setHandler(asyncResult -> {
    // ... handle result
});

方法2:

vertx.executeBlocking(future -> {
    executeLongRunningBlockingOperation();
    future.complete();
}, res -> {
    // ... handle result
});

解決方法は?

最初の例は Future . の呼び出しは executeLongRunningBlockingOperation() はそのメソッドが完了するまでメインスレッドをブロックします。つまり、ブロック処理が終了するまで他のことは何も起こりません。2番目の例では、ブロックされた呼び出しはバックグラウンドスレッドにスピンオフされ、それが実行される間、他のことが起こり続ける。

より完全な例で説明すると、このようなコードになります。

public void executeLongRunningBlockingOperation() {
    Thread.sleep(5000);
}

public Future<Void> doTheJob() { 
    System.out.println("Doing the job...");
    Future<Void> future = Future.future();
    executeLongRunningBlockingOperation();
    // this line will not be called until executeLongRunningBlockingOperation returns!
    future.complete();
    // nor will this method! This means that the method won't return until the long operation is done!
    return future;
}

public static void main(String[] args) {
    doTheJob().setHandler(asyncResult -> {
        System.out.println("Finished the job");
    });
    System.out.println("Doing other stuff in the mean time...");
}

次のような出力が得られます。

Doing the job...
Finished the job
Doing other stuff in the mean time...

このコードに対して(executeBlockingを使用する)。

...
public Future<Void> doTheJob() { 
    System.out.println("Doing the job...");
    Future<Void> future = Future.future();
    Vertx vertx = Vertx.vertx();
    vertx.executeBlocking(call -> {
        executeLongRunningBlockingOperation();
        call.complete;
    }, result -> {
        // this will only be called once the blocking operation is done
        future.complete();
    });
    // this method returns immediately since we are not blocking the main thread
    return future;
}
...

生産する予定です。

Doing the job...
Doing other stuff in the mean time...
Finished the job

Vert.xの理解を深めたい方は、以下のハンズオンチュートリアルをお勧めします。

https://vertx.io/docs/guide-for-java-devs/

http://escoffier.me/vertx-hol/