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操作系统(互斥量),所以说创建线程是一个性能很差的操作!
相关推荐
向前看-2 小时前
验证码机制
前端·后端
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
AskHarries6 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion7 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp7 小时前
Spring-AOP
java·后端·spring·spring-aop
TodoCoder7 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
凌虚8 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
机器之心9 小时前
图学习新突破:一个统一框架连接空域和频域
人工智能·后端
.生产的驴10 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
顽疲10 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端