gpt4 book ai didi

java - 如何在 Undertow 中的非阻塞处理程序中执行阻塞代码?

转载 作者:行者123 更新时间:2023-12-02 03:26:51 25 4
gpt4 key购买 nike

separate question 中所述,当使用Undertow时,所有处理都应该在专用的Worker线程池中完成,如下所示:

public class Start {

public static void main(String[] args) {
Undertow server = Undertow.builder()
.addListener(8080, "localhost")
.setHandler(new HttpHandler() {
public void handleRequest(HttpServerExchange exchange)
throws Exception {
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
exchange.getResponseHeaders()
.put(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender()
.send("Hello World");
}
})
.build();
server.start();
}
}

据我了解BlockingHandler可用于显式告诉 Undertow 将请求调度到专用线程池上以阻止请求。我们可以通过包装 HttpHandler 来调整上面的示例。在 BlockingHandler 的实例中,像这样:

        .setHandler(new BlockingHandler(new HttpHandler() {

这适用于我们知道始终阻塞的调用。

但是,如果某些代码大多数时候是非阻塞的,但有时需要阻塞调用,如何将阻塞调用变成非阻塞调用?例如,如果请求的值存在于缓存中,则以下代码不会阻塞(它只是从某些 Map<> 中获取),但如果不存在,则必须从数据库中获取。

public class Start {

public static void main(String[] args) {
Undertow server = Undertow.builder()
.addListener(8080, "localhost")
.setHandler(new HttpHandler() {
public void handleRequest(HttpServerExchange exchange)
throws Exception {
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
if (valueIsPresentInCache(exchange)) {
return valueFromCache; // non-blocking
} else {
return fetchValueFromDatabase(); // blocking!!!
}
}
})
.build();
server.start();
}
}

根据docs ,有一个方法HttpServerExchange.startBlocking() ,但根据 JavaDoc,除非您确实需要使用输入流,否则此调用仍然是阻塞调用。

Calling this method puts the exchange in blocking mode, and creates a BlockingHttpExchange object to store the streams. When an exchange is in blocking mode the input stream methods become available, other than that there is presently no major difference between blocking an non-blocking modes

如何将这种阻塞调用转变为非阻塞调用?

最佳答案

正确的方法是在IO线程中实际执行逻辑,如果它是非阻塞的。否则,将请求委托(delegate)给专用线程,如下所示:

public class Example {

public static void main(String[] args) {
Undertow server = Undertow.builder()
.addListener(8080, "localhost")
.setHandler(new HttpHandler() {
public void handleRequest(HttpServerExchange exchange)
throws Exception {

if (valueIsPresentInCache(exchange)) {
getValueFromCache(); // non-blocking, can be done from IO thread
} else {

if (exchange.isInIoThread()) {
exchange.dispatch(this);
// we return immediately, otherwise this request will be
// handled both in IO thread and a Worker thread, throwing
// an exception
return;
}

fetchValueFromDatabase(); // blocking!!!

}
}
})
.build();
server.start();
}
}

关于java - 如何在 Undertow 中的非阻塞处理程序中执行阻塞代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56903865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com