1.实验:模拟Java线程状态迁移过程
在《【运行时数据区】-并发编程-前置知识(4.并发编程基础)-6》中,我们分析了Java线程从JDK层面到JVM层面的状态迁移:
本文我们来尝试自己实现Java线程的状态迁移过程,进一步加深对这个状态迁移过程的理解。
2.简化:JVM调用链
- 如下是JVM调用链:
- 我们简化调用链如下:
3.模拟1:JVM注册JNI接口
- 如红框处,我们通过
System.load
方法,加载提供了JNI接口的动态库lib.so
文件。
4.模拟2:启动Java线程
如下图:
start()
方法模拟JDK的Thread.start()
方法,该方法调用了start0()
方法。start0()
方法模拟JDK的Thread.start0()
方法,该方法为JNI接口。
- 通过
javah
,我们生成了start0()
方法对应的C++头文件。
6.模拟3:创建native线程
- 在
start0()
方法的实现中,我们调用了pthread_create()
方法,创建native线程。
7.模拟4:等待
- 当CPU调度上一步我们创建的native线程,进入该线程的回调函数
java_start()
。 - 我们创建了标志位
flag
,它用于模拟JVM中记录native线程一系列状态的标志位,初始值为0,表示native线程处于INITIALIZED
状态。 - while循环导致native线程一直处于等待状态。
8.模拟5:打破循环
- 回到
start0
方法的实现,通过sleep了一段时间后修改flag
标志位,模拟JVM中经过一系列准备工作,将native线程设置为RUNNABLE状态
。 - 此时,native线程在
java_start()
中处于循环等待的状态被打破。
9.模拟6:回调JDK
- 当native线程在
java_start()
中处于循环等待的状态被打破后,通过JNI获得Java侧的Test对象,进一步回调Java侧Test对象的run()
方法。 - 这一步,就模拟了JVM在native线程变为
RUNNABLE
状态后回调JDK的Thread.run()
方法。
10.运行效果
- 运行我们的模拟程序,打印结果如下:
- 本次实验,最终模拟了JDK中创建Java线程,JVM中对应也创建native线程,native线程的状态迁移后回调Java线程的回调函数。