Vert.x虚拟线程模式下请求处理与await用法及阻塞问题咨询
Vert.x 4.5.0 + Java 21 虚拟线程下await方法的正确用法疑问
我正在用Java 21、Vert.x 4.5.0测试虚拟线程,想搞清楚Web服务器及处理器场景下await方法的正确用法。
初始实现与报错
先编写了基础服务器Verticle:
public class Server extends AbstractVerticle { @Override public void start() { try { Router router = Router.router(vertx); router.route("/health").handler(ctx -> { await(ctx.response().end()); }); vertx.createHttpServer() .requestHandler(router) .listen(8080); } catch (Throwable e) { e.printStackTrace(); } } } public static void main(String[] args) { Vertx.vertx().deployVerticle(new Server()); }
调用/health端点时触发错误:java.lang.IllegalStateException: Cannot be called on a Vert.x event-loop thread,原因是await阻塞了事件循环线程。
切换虚拟线程部署后的疑问
尝试添加ThreadingModel.VIRTUAL_THREAD部署Verticle:
public static void main(String[] args) { Vertx.vertx().deployVerticle(new Server(), new DeploymentOptions() .setThreadingModel(ThreadingModel.VIRTUAL_THREAD)); while (true) { } }
(注:必须加while(true),否则应用会立刻退出)
现在调用/health不再报错,但有两个疑问:
- 是否每个请求都会对应一个虚拟线程?
- 能不能移除
while(true)循环?
阻塞逻辑测试的问题
测试时故意把处理器改成阻塞逻辑:
router.route("/health").handler(ctx -> { System.out.println("Enter: " + Thread.currentThread().getName()); await(vertx.executeBlocking(() -> { System.out.println("Blocking: " + Thread.currentThread().getName()); Thread.sleep(10000); return null; })); System.out.println("Exit: " + Thread.currentThread().getName()); await(ctx.response().end()); });
并发两个请求时发现请求是串行执行的,服务器被阻塞,一开始疑惑是不是Thread.sleep的问题?
最终疑惑
把executeBlocking的ordered参数设为false后问题解决,但还是搞不懂:基于虚拟线程的处理器,为啥还要调用executeBlocking?
内容的提问来源于stack exchange,提问作者Jonathan R
相关产品推荐
相关产品推荐

