Java线程Hotspot线程Linux线程源码穿透
原理分析
首先不妨先看一副图
通常我们在Java开发中使用线程无非就是使用Thread类提供的一些API,比如new Thread()、Thread.start() 等等方法。那么对于Linux操作系统而言是没有线程概念的,线程的概念是在glibc(操作系统API的一部分)层抽象出来的实现,是提供给Linux系统开发者使用的。目的是控制进程资源的使用。所以这里对应的线程/进程实体在如下三层都有体现:
- JDK层:Java线程对象。
- glibc层:c语言实现的对象c/c++开发者的线程对象。
- 内核层:进程对象task_struct,Linux任务调度的实体,在Linux只要是一个task_struct就可以调度。
那么我们的JVM如何完成不同层线程之间的联系呢?
首先glibc层的线程对象本来就是基于内核层的进程实体task_struct抽象出来的,不用我们关心,我们在JVM层需要关心的是如何完成glibc层的线程对象与JDK层的线程对象对应关系维护。
实现:
其实对于JDK层的Java线程对象,在JVM层也有一个c语言描述的线程对象,否则JVM又该如何控制JDK层的Java线程对象呢?当然这个也可以从JDK层有本地方法看得出来,否则本地方法又该如何关联到Java线程呢?
上图中可见JDK层和JVM层都有线程对象,两者合并完成Java线程的所有功能。那么JVM层的线程对象有了,glibc层的线程对象也有了,我们需要在jvm层做个线程映射来完成两层之间的线程关联即可。
下文主要围绕,具体源码分析展开。
Java层Thread
先看个demo
节奏我们深入Thread.java来看下
由以上代码可知:
1、Thread类在被加载的时候,首先会执行静态代码块,调用本地方法registerNatives去注册所有的本地方法。
2、在new Thread的过程中会执行如下核心逻辑:
1)设置线程的名字。
2)获取调用线程是否是守护线程及优先级并设置到当前线程。
3)设置线程的执行体到线程对象中。
4)最后重新设置优先级
3、然后执行start方法执行线程体,调用本地方法start0执行线程体。
综上所述,我们可以清楚知道,本地线程的创建和java线程与本地线程的映射的逻辑是在native层完成的。据此我们主要分析两个native方法的执行逻辑:
1)registerNatives :所有本地方法的注册。
2)start0 :创建本地线程并执行java线程体。
JVM层Thread
线程接口的注册
据此我们需要翻越jdk的源码,我用的openjdk1.8源码。
那么在java层线程对应的实现在 Thread.java,同样在JVM层叫Thread.c
启动线程的入口JVM_StartThread
由以上代码可以看到所有Thread.java中的本地方法都在这里注册。好,接下来我们看start0的本地实现JVM_StartThread
JVM层的JavaThread实体
继续追进 new JavaThread(&thread_entry, sz);
JVM映射JavaThread与glibc的Thread
继续追追进去 os::create_thread(this, thr_type, stack_sz); 我们选择linux的线程实现
启动JavaThread
继续追进 java_start
何时解除sync->wait
好了,到这里java线程的创建与执行基本已经分析完了,但是还差一点,那就是上面的代码的阻塞何时解除?因为解除阻塞以后才能执行thread->run,进而执行Runnable的的实现,真正执行我们的java代码。要回答这个问题我们需要往前看,还记得本地线程创建的入口吗?
这里的 Thread::start(native_thread); 我们追进去看一下
这里的Thread::start会解除线程的阻塞进而执行run方法。
结语
由于此篇文章仅对从Java线程到本地线程作讨论叙述,不涉及线程的其他方面知识,所有代码均来自openjdk,在此只是作简要删减,目的是为了让读者更容易理解,不喜勿喷,欢迎点赞收藏~~~。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构