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
经验总结扩展阅读
- 第一篇 TTD 专题 :C# 那些短命线程都在干什么?
- Java并发编程 | 从进程、线程到并发问题实例解决
- 七 Netty 学习:NioEventLoop 对应线程的创建和启动源码说明
- 云原生虚拟网络 tun/tap & veth-pair
- 补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析
- 附Anaconda安装包 Anaconda安装和卸载+虚拟环境Tensorflow安装以及末尾问题大全,这一篇就够了!!!
- 虚拟发货怎么确认收货
- 建议收藏 Java线程同步的四种方式详解
- 用AR Engine手部骨骼跟踪能力实现虚拟手表试戴
- 通过Thread Pool Executor类解析线程池执行任务的核心流程