文章插图
然后编写和运行下面的例子:
import jdk.internal.vm.Continuation;import jdk.internal.vm.ContinuationScope;public class ContinuationDemo { public static void main(String[] args) { ContinuationScope scope = new ContinuationScope("scope"); Continuation continuation = new Continuation(scope, () -> { System.out.println("Running before yield"); Continuation.yield(scope); System.out.println("Running after yield"); }); System.out.println("First run"); // 第一次执行Continuation.run continuation.run(); System.out.println("Second run"); // 第二次执行Continuation.run continuation.run(); System.out.println("Done"); }}// 运行代码,神奇的结果出现了First runRunning before yieldSecond runRunning after yieldDone这里可以看出Continuation的奇妙之处,Continuation实例进行yield调用后,再次调用其run方法就可以从yield的调用之处往下执行,从而实现了程序的中断和恢复 。
源码分析主要包括:
- Continuation
- VirtualThread
- 线程建造器
// 判断是否需要保留当前线程的本地缓存,由系统参数jdk.preserveExtentLocalCache决定private static final boolean PRESERVE_EXTENT_LOCAL_CACHE;// 真正要被执行的任务实例private final Runnable target;// 标识Continuation的范围,private final ContinuationScope scope;// Continuation的父节点,如果为空的时候则为本地线程栈private Continuation parent;// Continuation的子节点,非空时候说明在子Continuation中进行了yield操作private Continuation child;// 猜测为Continuation栈结构,由JVM管理,无法得知其真实作用private StackChunk tail;// 标记Continuation是否已经完成private boolean done;// 标记是否进行了mount操作private volatile boolean mounted = false;// yield操作时候设置的信息private Object yieldInfo;// 标记一个未挂载的Continuation是否通过强制抢占式卸载private boolean preempted;// 保留当前线程的本地缓存的副本private Object[] extentLocalCache;// 构造函数,要求传入范围和任务包装实例public Continuation(ContinuationScope scope, Runnable target) { this.scope = scope; this.target = target;}
经验总结扩展阅读
- 第一篇 TTD 专题 :C# 那些短命线程都在干什么?
- Java并发编程 | 从进程、线程到并发问题实例解决
- 七 Netty 学习:NioEventLoop 对应线程的创建和启动源码说明
- 云原生虚拟网络 tun/tap & veth-pair
- 补充部分---ScheduledThreadPoolExecutor类分析 线程池底层原理详解与源码分析
- 附Anaconda安装包 Anaconda安装和卸载+虚拟环境Tensorflow安装以及末尾问题大全,这一篇就够了!!!
- 虚拟发货怎么确认收货
- 建议收藏 Java线程同步的四种方式详解
- 用AR Engine手部骨骼跟踪能力实现虚拟手表试戴
- 通过Thread Pool Executor类解析线程池执行任务的核心流程