Vertx:executeBlocking() 与 Future。有什么不同?

Eva*_*van 3 java asynchronous vert.x

Vertx 文档建议executeBlocking()在需要调用阻塞 API 时使用方法。另一方面,Vertx 还提供了一个 Future 的概念,它基本上做同样的事情。但该executeBlocking()方法不是静态的。它也不是 Future 的简单包装器,如果您查看它的实现,您会发现它非常复杂。这两者有什么区别?

假设我想以异步方式执行一些长时间运行的任务。这两种方法有什么区别吗?

方法一:

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

doTheJob().setHandler(asyncResult -> {
    // ... handle result
});
Run Code Online (Sandbox Code Playgroud)

方法二:

vertx.executeBlocking(future -> {
    executeLongRunningBlockingOperation();
    future.complete();
}, res -> {
    // ... handle result
});
Run Code Online (Sandbox Code Playgroud)

小智 9

您的第一个示例不是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...");
}
Run Code Online (Sandbox Code Playgroud)

将产生以下输出:

Doing the job...
Finished the job
Doing other stuff in the mean time...
Run Code Online (Sandbox Code Playgroud)

而这段代码(使用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;
}
...
Run Code Online (Sandbox Code Playgroud)

将产生:

Doing the job...
Doing other stuff in the mean time...
Finished the job
Run Code Online (Sandbox Code Playgroud)

如果你想更好地理解 Vert.x,我推荐以下动手教程:

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

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