Vertx文档建议当需要调用阻止API时使用executeBlocking()
方法。另一方面,Vertx还提供了“ Future”(未来)概念,该概念基本上可以完成相同的操作。但是executeBlocking()
方法不是静态的。它也不是对Future的简单包装,如果您查看它的implementation,将会发现它非常复杂。两者有什么区别?
假设我想以异步方式执行一些长时间运行的任务。这两种方法有什么区别?
方法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
});
答案 0 :(得分:2)
您的第一个示例不是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,建议您参考以下动手教程: