当前位置: 首页 > 知识库问答 >
问题:

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

范哲
2023-03-14

如另一个问题中所述,当使用Undertow时,所有处理都应该在专用的工作线程池中完成,如下所示:

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() {
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();
  }
}

调用此方法将exchange置于阻塞模式,并创建一个BlockingHttpExchange对象来存储流。当交换处于阻塞模式时,输入流方法变得可用,除了阻塞和非阻塞模式之间目前没有主要区别之外

如何将这个阻塞调用转换为非阻塞调用?

共有1个答案

朱宇航
2023-03-14

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

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();
  }
}
 类似资料:
  • 问题内容: 我有这段代码可以在Linux中从Serial读取,但是我不知道在读取SerialPort时阻塞和非阻塞之间有什么区别,在哪种情况下哪个更好? 问题答案: 您提到的代码是IMO编码和注释不当的代码。该代码不符合POSIX的可移植性惯例,如正确设置终端模式和POSIX操作系统的串行编程指南中所述。该代码没有提到它使用非规范(也称为原始)模式,并且重用了“阻塞”和“非阻塞”术语来描述 VMI

  • 我完全混淆了,,。 哪个是阻塞,哪个不是? 我的意思是如果我使用父进程是否等待子进程返回/才继续执行。 如何影响这些调用?

  • 本文向大家介绍了解节点中代码执行的阻塞和解除阻塞,包括了了解节点中代码执行的阻塞和解除阻塞的使用技巧和注意事项,需要的朋友参考一下 现在,我们在fs模块中具有文件写入功能writeFileSync,如下所示- 同步表示已同步。这是一个阻塞代码示例。一旦文件写入完成,则仅对其余文件执行代码。上面的代码比较简单,但是如果我们进行大量的文件处理操作,将会导致应用性能下降。 这种代码执行方式将减慢其他请求

  • 非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser

  • Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S

  • 问题内容: 我可以很轻松地在Node.js中编写非阻塞I / O。 这就是整个库的用途。 但是所做的任何计算都是阻塞的。任何通过事件发送器的消息都将被阻止。 例如,发出事件立即得到解决,因此被阻止: 除了将调用包装起来外,如何使代码无阻塞? 我希望在事件循环的每个周期中进行尽可能少的计算,以便可以同时为尽可能多的客户端提供服务。 如何以非阻塞方式编写代码? 当我拥有非阻塞代码时,如何在多个进程之间