源码debug 线程start0 方法,一步一步debug,java openjdk 源码解析 职场进阶

本文详细解析了Java线程创建的底层过程,包括thread.c和jvm.cpp的关键代码段,从native_thread的创建,到java_start方法的执行,再到run方法的回调。通过debug步骤,揭示了并发执行的全貌。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1为什么要看这个源码

2. debug 步骤

       1.1既然是thread 类,我们先看到 thread.c 中找

1.2既然是 jvm的,就在jvm.cpp上打断点了 2817行

3我们跳入到 2851行

4可以看出 这里是javaThread的一个构造方法 ,我们进去 thread.cpp 1570 行

5java_start 方法是在哪里呢? os_linux.cpp 806行,我们看看这个方法到底在干嘛

6还记得创建线程是哪里吗 ?jvm.cpp 2851 行,我们接着往下走 到 2884 行

7此时java_start 方法继续执行 os_linux.cpp 中判断线程状态已经是running了,所以放行。860行

8跳转到 thread.cpp 1679行 真正执行run方法的回调以及线程销毁

总结下:


1为什么要看这个源码

  1. 熟悉源码,了解底层 知彼知己。平时我们就写start方法 反正就会调用run方法。不可靠源码总觉得模糊,不可靠。

  2. 作为一个线程的启动过程,其实也是main线程启动流程的一部分,因为main本身也是线程嘛,上次课说过main的启动流程,再次梳理下线程的流程也算是巩固下知识。

2. debug 步骤

       1.1既然是thread 类,我们先看到 thread.c 中找

1.2既然是 jvm的,就在jvm.cpp上打断点了 2817行

  1. 3我们跳入到 2851行

native_thread = new JavaThread(&thread_entry, sz); //创建一个对应的内核线程,这里注意thread_entry,后续会执行这个方法

  1. 4可以看出 这里是javaThread的一个构造方法 ,我们进去 thread.cpp 1570 行

set_entry_point(entry_point);              //这里要注意:run方法回调入口点在这里设置进去了

1576行,创建原生线程

我们进入看看发生了什么,跳入到 os_linux.cpp 865行

// Allocate the OSThread object
OSThread* osthread = new OSThread(NULL, NULL);  //OSThread是java线程和内核线程直接的桥梁
if (osthread == NULL) {
  return false;
}


// set the correct thread state
osthread->set_thread_type(thr_type);


// Initial state is ALLOCATED but not INITIALIZED
osthread->set_state(ALLOCATED);


thread->set_osthread(osthread);        //先将osthread与java thread关联

跳转到 934行 真正的 创建内核线程,并等待java_start 方法

int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); //创建对应的内核线程,并启动线程(执行java_start方法,并阻塞)

  1. 5java_start 方法是在哪里呢? os_linux.cpp 806行,我们看看这个方法到底在干嘛

我们跳转到854行

// wait until os::start_thread()
while (osthread->get_state() == INITIALIZED) {   //这里会循环阻塞,一直等到线程状态为runnable才往下执行
  sync->wait(Mutex::_no_safepoint_check_flag);
}

也就是说 java_start 方法一直在while循环 ,如果线程状态一直是 INITIALIZED ,就一直while循环 不往下执行。

  1. 6还记得创建线程是哪里吗 ?jvm.cpp 2851 行,我们接着往下走 到 2884 行

Thread::start(native_thread);  //启动线程,主要是设置状态为RUNNABLE(java_start方法中会感知,然后initialized状态修改为RUNNABLE,流程继续往下调用run方法)

点进入到 thread.cpp 464行

继续跟进到 os_linux.cpp 863

osthread->set_state(RUNNABLE);    //这里设置线程状态为RUNNABLE状态,很重要,设置完之后在java_start方法中感知

  1. 7此时java_start 方法继续执行 os_linux.cpp 中判断线程状态已经是running了,所以放行。860行

thread->run(); 

  1. 8跳转到 thread.cpp 1679行 真正执行run方法的回调以及线程销毁

thread_main_inner();   //这个方法很重要,会调线程入口.执行具体的run方法并在执行完成销毁当前实例

继续到 1699行 回调run方法

this->entry_point()(this, this);  //回调线程run入口。执行entry_point函数,就是执行Thread的run方法

OK! 此时 流程已经全部走完了。 还是比较简单的吧。

总结下:

创建个线程,并发run回调入口设置进去,然后创建个内核线程,并等待java_start 方法的完成,java_start 方法判断线程状态如果是 初始化 就一直while循环,直到线程状态改变就继续执行 最后回调run方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫猫大神

有帮助的话,请打赏官人一下哦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值