支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程( 三 )


支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 至此就要先打住了,不要急着看BlockingHandler的代码,那里面的东西是在处理web请求时才会执行 , 到目前为止咱们的重点还只是分析Executors.newVirtualThreadPerTaskExecutor()方法创建的executor去了哪里,现在就小结一下吧
  • 一图胜千言,本篇最核心的Executor对象的诞生过程,由一个主线逻辑和两个支线逻辑组成,如下图,红色代表主线任务 , 它负责遍历所有web接口对应的方法,发现该方法需要用虚拟线程执行时 , 就为此方法绑定一个BlockingHandler对象,这个handler的成员变量中,就有直线逻辑用JDK19特定的方法创建出来的虚拟线程特有的executor对象,至于这个handler对象怎么用?就是本篇的另一半重要内容了:执行虚拟线程

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 至此,本篇的第二个重要问题:这个特别的Executor对象是哪来的,这个问题已经弄明白了(好像一句话就能说清楚:放入了和web接口方法关联的handler中),接下来是最后一个问题:这个特别的Executor对象应该怎么用?
这个特别的Executor对象应该怎么用?
  • 由于虚拟线程是在处理web响应的时候被用到的 , 所以分析这个特别的Executor对象时,不可避免的进入了quarkus处理web响应的复杂逻辑中,之所以说复杂,因为这里面最底层涉及到netty , 再往上又涉及到vertx库,如果咱们从头去看会严重偏离主题 , 所以接下来分析web响应的代码时 , 我这边就尽量简化了
  • 代码分析中RestInitialHandler#beginProcessing方法开始吧,对于反应式web服务,每次请求都会执行此方法,如下图,红色箭头指向的ResteasyReactiveRequestContext对象需要重点关注,这里面放置了本次web请求的相关信息,接下来就会执行此对象的run方法

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 打开run方法,豁然开朗,前面咱们看到为web接口方法绑定handler,这里会取出handler依次执行

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 上图的方法是在中实现的 , 打开代码后吓了我一跳,估计quarkus的人也怕被喷,在注释中看到了他们满满的求生欲:代码写成这样是为了性能考虑,这样写就是单态调用,取代了简化写法中的多态调用 , 会有更好的性能表现(不敢说学到了新技术,只能说开阔了眼界)

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 上面的代码其实就是调用hanler的handle方法,所以,是时候去看那个BlockingHandler的handler方法了
  • 刚打开代码就大呼一声痛快!如下图,handler将虚拟线程的executor和web请求的上下文对象requestContext串起来了,接下来该去箭头2所指的resume中一探究竟,我这里大胆的猜一下,resume方法中要做的事情应该和Runnable有关,理由很简单:Runnable和Executor不就是配合着用的嘛

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 上图箭头2的代码在AbstractResteasyReactiveContext.java中,先看这个AbstractResteasyReactiveContext类,果然实现了Runnable

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 接下来该看AbstractResteasyReactiveContext#resume方法了,看之前我猜应该是executor.execute(this),因为我只会这么写... , 打开代码一看就乐了,原来我只会这么写就够了,因为他们也是这么写的,注意箭头2 , 本文的核心也就是这段代码了

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 写到这里,关于executor的使用也全部分析完了 , 用一个简化图小结吧

支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程

文章插图
  • 至此,quarkus支持虚拟线程的相关代码已经阅读完毕,这里再做个小结:
  1. 咱们在web接口类上添加的@RunOnVirtualThread注解,会存入每个web接口方法对应的ResourceMethod对象中
  2. 应用在初始化的时候,检查web接口方法对应的ResourceMethod对象,如果需要在虚拟线程中响应,就给这个web接口绑定一个BlockingHandler对象,此对象有个成员变量 , 是个executor,是通过Executors.newVirtualThreadPerTaskExecutor()方法创建的

    推荐阅读