虚拟线程 - VirtualThread源码透视( 九 )

ForkJoinPool#lazySubmit()是JDK19新增的一个API,它的方法注释如下:

提交给定的任务,但不保证它最终会在没有可用活动线程的情况下执行 。在某些上下文中,这种方法可以通过依赖于特定于上下文的知识来减少竞争和开销,即现有线程(如果在此池中操作,则可能包括调用线程)最终将可用来执行任务
使用此方法提交的目的就是希望可以用当前调用线程去执行任务,对于首次提交Continuation任务可能作用不明显,但是对于Continuation.yield()调用后的再次提交意义比较重大,因为这样就可以把运行的Continuation.run()方法链分配到同一个运载线程实例,在开发者的角度就是虚拟线程任务执行中断后恢复执行,执行任务的运载线程没有改变 。
源码中还可以发现,run()方法覆盖了Thread#run()替换为空实现,因为VirtualThread最终是触发Continuation#run(),这一点已经在start()方法进行提交和调度 。最后分析虚拟线程的阻塞(不带超时,也就是timeout = 0)、限时阻塞(timeout > 0)、join的实现 。先看相对简单的joinNanos():
// java.lang.VirtualThread// Thread.join() --> VirtualThread.joinNanos()// 虚拟线程join调用boolean joinNanos(long nanos) throws InterruptedException {    // 如果状态为TERMINATED直接返回true    if (state() == TERMINATED)        return true;    // 获取数栅栏实例    CountDownLatch termination = getTermination();    // 再次验证如果状态为TERMINATED直接返回true    if (state() == TERMINATED)        return true;    // 如果nanos为0则调用CountDownLatch.await()阻塞    if (nanos == 0) {        termination.await();    } else {        // 如果nanos大于0则调用CountDownLatch.await(nanos,TimeUnit)限时阻塞        boolean terminated = termination.await(nanos, NANOSECONDS);        if (!terminated) {            // 阻塞到超时时限过了返回,非解除阻塞下的正常返回            return false;        }    }    assert state() == TERMINATED;    // 解除阻塞下的正常返回    return true;}// 懒创建终结倒数栅栏实例,设置资源值为1,这里用到CAS是考虑之前已经创建和保存到成员变量,如果已创建则直接选用成员变量的那个实例private CountDownLatch getTermination() {    CountDownLatch termination = this.termination;    if (termination == null) {        termination = new CountDownLatch(1);        if (!U.compareAndSetReference(this, TERMINATION, null, termination)) {            termination = this.termination;        }    }    return termination;}接着看虚拟线程阻塞和限时阻塞的现实:
// java.lang.VirtualThread// Thread.sleep() --> VirtualThread.sleepNanos()// 给定休眠时间让当前虚拟线程休眠void sleepNanos(long nanos) throws InterruptedException {    assert Thread.currentThread() == this;    // n

经验总结扩展阅读