Java线程是怎么实现run方法的执行的呢?【 多线程在JVM中的实现原理剖析】

@[TOC](Java线程是怎么实现run方法的执行的呢?【 多线程在JVM中的实现原理剖析】)

本文转载-极客时间

我们知道Java线程是通过行start()方法来启动的,线程启动后会执行run方法内的代码。 Java线程其实是"寄生"在操作系统线程上,通过操作系统的线程来实现Java线程的运行。接下来我们就深入源码来看看Java线程是怎么实现"寄生"在操作系统线程上来运行的。

java 复制代码
package com.hero.multithreading;
public class ThreadDemo {
	public static void main(String[] args) {
		Thread thread =new Thread(()->{
			System.out.println("线程");
		});
		thread.start();
	}
}

查看naive state0 方法

从入口开始,首先我们进入到Thread类的start方法内,可以看到有一个start0()方法的调用, 这里是真正启动Java线程的地方 。

start0是一个 native方法, 那么start0方法是在哪里实现的呢? 在openjdk源码share\native\java\lang\Thread.c 文件中我们可以找到start0的定义,Java 线程将start0方法和真正的实现方法JVM_StartThread进行了绑定。也就是说调用start0相当与调用了JVM_StartThread方法。 JNINativeMethod类型的结构体变量,JNINativeMethod定义在jni.h中。定义了一个native方法和jni方法的映射关系,将Java中的native方法和JVM中真正的实现方法进行绑定。

那么这里就有一个问题,registerNatives方法具体是在哪里何时执行映射操作的呢? 在JVM首次加载Thread类的时候,在Thread类的静态初始化块中,调用了native registerNatives方法,它对应的Jni方法就是上面的Java_java_lang_Thread_registerNatives方法,就是在这里完成了state0和JVM_StartThread的绑定。

JVM_StartThread 方法

至此,我们知道执行state0方法就是执行JVM_StartThread方法,它定义在hotspot JVM源码文件src\share\vm\prims\jvm.cpp 中。

创建操作系统线程

JVM在所有的操作系统中都实现了os::create_thread,我们看linux操作系统的实现在src\os\linux\vm\os_linux.cpp 中

操作系统线程执行

至此一个操作系统线程创建及初始化完毕了,我们返回到步骤1.2.3中的JVM_StartThread 方法中,最后一行Thread::start(native_thread); 开始执行操作系统线程。 至此,操作系统线程为就绪状态,等待被CPU选中运行时,就会调用执行入口函数java_start,调用Java线程的run方法,至此Java线程也就同时运行起来了。

小结一下

  1. 线程类被JVM加载时,完成线程所有native方法和C++中的对应方法绑定。
  2. Java线程调用start方法:start方法 => native state0方法 => JVM_StartThread => 创建JavaThread::JavaThread线程
  3. 创建OS线程,并指定OS线程的运行入口:创建JavaThread::JavaThread线程 => 创建OS线程 os::create_thread => 指定OS线程执行入口Java线程的run方法
  4. 启动OS线程:运行时会调用Java线程的run方法,至此实现了Java线程的运行。
  5. 创建线程的时候使用的是互斥锁MutexLocker操作系统(互斥量),所以说创建线程是一个性能很差的操作!
相关推荐
雨落倾城夏未凉17 分钟前
5.通过拷贝构造函数复制一个对象,假如对象的成员中有个指针类型的变量,如何避免拷贝出来的副本中的该成员之下行同一块内存(等价于默认拷贝构造函数有没有缺点)
c++·后端
雨落倾城夏未凉19 分钟前
4.深拷贝VS浅拷贝
c++·后端
dl74322 分钟前
一文看懂spring配置原理
后端
ERP老兵_冷溪虎山25 分钟前
IDEA 幽灵触手实锤!Python 文件一开,Anaconda 全局库让 JDK 编译慢 2-4 秒(附截图证据)
后端
阿华的代码王国32 分钟前
【Android】适配器与外部事件的交互
android·xml·java·前端·后端·交互
写bug写bug33 分钟前
分布式锁的使用场景和常见实现(下)
分布式·后端·面试
Postkarte不想说话34 分钟前
Debian13编译安装FreeSWITCH
后端
SimonKing38 分钟前
Mybatis批量插入,形式不同性能也不同
数据库·后端·程序员
MacroZheng42 分钟前
还在用WebSocket实现即时通讯?试试MQTT吧,真香!
java·spring boot·后端
midsummer_woo1 小时前
基于springboot的IT技术交流和分享平台的设计与实现(源码+论文)
java·spring boot·后端