Java虚拟线程(三)实现原理
https://mp.weixin.qq.com/s/vdLXhZdWyxc6K-D3Aj03LA
import jdk.internal.vm.Continuation;
import jdk.internal.vm.ContinuationScope;
public class ContinuteTest {
public static void main(String[] args) {
ContinuationScope scope = new ContinuationScope("scope");
Continuation continuation = new Continuation(scope, () -> {
System.out.println("before yield开始");
Continuation.yield(scope); // 这里会从载体线程卸载
System.out.println("after yield 结束");
});
System.out.println("1 run");// 第一次执行Continuation.run
continuation.run();
System.out.println("2 run");// 第二次执行Continuation.run
continuation.run();
System.out.println("Done"); //执行了两次run才让Continuation里边的runnable跑完
}
}
这里是有两组线程:我们自己通过Continuation来模拟的虚拟线程(实际上Java虚拟线程底层也就是这东西);以及主线程、它成为平台线程(跟os线程是1:1),此时它也是我们模拟的虚拟线程的载体线程。
Java虚拟线程的本质就是用Continuation封装Runnable, 如上所示,Continuation 执行过程中可以使用yield使之从载体线程卸载,再次执行run()将会继续执行Continuation的runnable逻辑。
卸载这个过程是native代码,JVM做的事情,对开发者透明。这个过程中会将载体线程此时的线程栈中涉及虚拟线程执行的栈帧(从run到yield之间)复制到堆中(没错,虚拟线程的“线程栈”是在堆里的),然后清空,载体线程就继续被ForkJoinPool (注:我们这个例子只是主线程,不涉及ForkJoinPool)调度去干别的事情。
第二次continuation.run()恢复执行,那么JVM做相反的事情,从堆中恢复之前的快照到载体线程栈,继续执行。
浙公网安备 33010602011771号