Vertx: executeBlocking () против будущего.Какая разница? - PullRequest
0 голосов
/ 30 сентября 2018

Vertx docs предлагает использовать метод executeBlocking(), когда нужно вызвать API блокировки.С другой стороны, Vertx также предлагает понятие будущего, которое в основном делает то же самое.Но метод executeBlocking() не является статичным.Это также не простая оболочка для Future, и если вы посмотрите на ее реализацию , то увидите, что она довольно сложная.В чем разница между этими двумя?

Предположим, что я хочу выполнить какое-то длительное задание асинхронно.Есть ли разница между этими двумя методами?

метод 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
});

1 Ответ

0 голосов
/ 01 октября 2018

Ваш первый пример неправильного использования Future.Вызов executeLongRunningBlockingOperation() блокирует основной поток до тех пор, пока этот метод не завершится - т.е. больше ничего не может произойти, пока операция блокировки не завершится.Во втором примере блокирующий вызов выполняется в фоновом потоке, и во время его выполнения продолжают происходить другие вещи.

Чтобы проиллюстрировать это на более полном примере, этот код:

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/

...