英文:
Does Vert.x support the operation of converting asynchronous results to synchronous ones?
问题
I have a method with a synchronous return value, but it internally calls an asynchronous operation.
现在我使用 ".toCompletionStage().toCompletableFuture().get"。但是我遇到了线程阻塞的问题。我很困惑,怀疑与线程池有关。谁可以帮我解释这个问题?
public String load(){
Future<String> future = /* sample code return future*/;
String data = future.toCompletionStage().toCompletableFuture().get();
return data;
}
vertx.consumer("topic", req->{
String data = load();
req.reply(data);
}
当我请求 "topic" 时,它会阻塞事件循环线程。
英文:
I have a method with a synchronous return value, but it internally calls an asynchronous operation.
Now I use ".toCompletionStage().toCompletableFuture().get". But I have encountered blocked thread problems. I am very confused and suspect it's related to the thread pool. Who can help me explain this?
public String load(){
Future<String> future = /* sample code return future*/;
String data = future.toCompletionStage().toCompletableFuture().get();
return data;
}
vertx.consumer("topic", req->{
String data = load();
req.reply(data);
}
When I request the "topic", it will block eventloop thread.
答案1
得分: 1
"Converting" a Future
would mean to block execution until the result is available. And that's against Vert.x No. 1 rule - never block the event loops.
Reason for this is that an event loop has only one thread to deal all I/O events. If you block it, all other events (requests, file system operations etc.) will need to wait.
That's why vertx-blocked-thread-checker
is unhappy and warns you, so you have a chance to fix the issue.
The load
method in your example should just return Future<String>
. That way, you defer processing of load()
's result until it is available. All calling methods will have to adapt and also work with or return Future
. If that seems strange, there are many discussions about function coloring out there...
load()
should look like this:
public Future<String> load() {
return /* sample code return future*/
}
And the call site should look like this:
vertx.consumer("topic", req -> {
load().onSuccess(data -> req.reply(data));
});
Note how the code declares now what needs to be done after the result is available.
英文:
Short answer: No. "Converting" a Future
would mean to block execution until the result is available. And that's against Vert.x No. 1 rule - never block the event loops.
Reason for this is that an event loop has only one thread to deal all I/O events. If you block it, all other events (requests, file system operations etc.) will need to wait.
That's why vertx-blocked-thread-checker
is unhappy and warns you, so you have a chance to fix the issue.
The load
method in your example should just return Future<String>
. That way, you defer processing of load()
's result until it is available. All calling methods will have to adapt and also work with or return Future
. If that seems strange, there are many discussions about function coloring out there...
load()
should look like this:
public Future<String> load() {
return /* sample code return future*/
}
And the call site should look like this:
vertx.consumer("topic", req -> {
load().onSuccess(data -> req.reply(data));
});
Note how the code declares now what needs to be done after the result is available.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论