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

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

    • 查看naive state0 方法
    • JVM_StartThread 方法
    • 创建操作系统线程
    • 操作系统线程执行

本文转载-极客时间

我们知道Java线程是通过行start()方法来启动的,线程启动后会执行run方法内的代码。
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操作系统(互斥量),所以说创建线程是一个性能很差的操作!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/673819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据可视化教程!我将全程出镜解说

你好,我是郭震 数据和算力是助推AI成功的关键二要素,洞察数据背后奥秘的重要手段之一便是数据可视化。 数据可视化无论在论文发表,还是商业数据分析中都扮演着举足轻重的作用。 一句话:一图胜千言。 从今天开始,我会逐…

FATFS学习笔记——FATFS写文件的两种方式

1.以hex文件直接写: 适用于需要保存比较大的数据时,无需进行格式化处理,直接保存文件 FIL file;FRESULT res;UINT bytes_written;// 创建文件res f_open(&file, "0:/FATFS/TestData.txt", FA_CREATE_ALWAYS | FA_WRITE);if (res ! FR_OK…

【Script】使用pyOpenAnnotate搭建半自动标注工具(附python源码)

文章目录 0. Background1. Method2. Code3. Example: 雄鹿红外图像标注3.1 选择色彩空间3.2 执行阈值3.3 执行形态学操作3.4 轮廓分析以找到边界框3.5 过滤不需要的轮廓3.6 绘制边界框3.7 以需要的格式保存Reference本文将手把手教你用Python和OpenCV搭建一个半自动标注工具(包…

【项目源码】一套基于springboot+Uniapp框架开发的智慧医院3D人体导诊系统源码

智慧医院3D人体导诊系统源码 开发语言:java 开发工具:IDEA 前端框架:Uniapp 后端框架:springboot 数 据 库:mysql 移 动 端:微信小程序、H5 “智慧导诊”以人工智能手段为依托,为人们提供智能分诊、问病信息等服务,在一定程度上满足了人们自我健康管理、精准挂号…

6个好看的wordpress模板

简站wordpress服务业通用主题 2023年立秋纪念版,简站wordpress服务行业通用主题,适合服务行业企业官网使用。 https://www.jianzhanpress.com/?p5393 小语种翻译wordpress主题 小语种国家外贸网站建设需要的wordpress主题模板,适合做小语…

单链表实现约瑟夫环

大家对约瑟夫环是比较陌生的,但是对于大多数人来说,丢手绢却一点都不陌生,其实约瑟夫环和丢手绢差不多。 约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。…

Android 10.0 系统sim卡4G LTE信号格数对应的信号强度值修改

1.前言 在10.0的系统产品开发中,在手机通讯这块功能也是特别重要的,在手机插入手机sim卡后,会根据当前的sim卡信号来显示对应的 sim卡信号显示格数,所以为了增强相关的信号格数,就需要修改sim卡对应的信号强度值来实现相关的功能 2.系统sim卡4G LTE信号格数对应的信号强…

分享78个行业PPT,总有一款适合您

分享78个行业PPT,总有一款适合您 78个行业PPT下载链接:https://pan.baidu.com/s/19UL58I5Z1QZidVrq50v6fg?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集整理更不易…

海信电视安装第三方软件-电视家分享(侵权联系作者删除)

1.海信电视安装第三方软件电视家,相对来说还是比较复杂的。首先要准备电视安装包,一般来说是电视家海信专用安装包,大家可以搜索电视家的官方网站。这里附上官网地址https://www.tvapk.net/dianshijia/ 点击上方的电视软件。 可以进入下载软…

中兴R5300G4服务器查看服务器、主板序列号及硬盘RAID信息

本文在操作系统带内通过指令操作查看中兴R5300G4服务器、主板序列号及硬盘RAID信息。 一、中兴R5300G4服务器查看服务器、主板序列号 在Linux服务器上,可以使用dmidecode命令来查看服务器的硬件相关信息,由于该命令要读取系统的硬件信息,因…

阅读《极客时间 | Kafka核心技术与实战》(一)【Kafka入门】

阅读《极客时间 | Kafka核心技术与实战》 为什么要学习Kafka消息引擎系统ABC一篇文章带你快速搞定Kafka术语我应该选择哪种Kafka?聊聊Kafka的版本号 为什么要学习Kafka 如果你是一名软件开发工程师的话,掌握 Kafka 的第一步就是要根据你掌握的编程语言去…

MPLS VPN功能组件(2)

MP-BGP 采用地址族(Address Family)来区分不同的网络层协议,以便正确处理VPN-IPv4路由 传统的BGP-4(RFC1771)只能管理IPv4的路由信息,无法正确处理地址空间重叠的VPN的路由。 为了正确处理VPN路由,VPN使用RFC2858(Multiprotocol Extensions for BGP-4)中规定的MP-BG…

Vue3.0(四):Composition API的使用

Composition API 认识Composition API 前几篇文章中主要用Options API进行编写代码,但是有一些弊端 Options API弊端 在 Options API中,有data、watch、computed、methods以及生命周期函数各种各样的选项而一个变量,为了实现某个功能&#x…

【数据分析岗】8家知名企业秋招(含实习)面试题汇总

年底了,技术群组织了一场机器学习算法岗技术&面试讨论会,邀请了一些同学分享他们的面试经历,讨论会会定期召开,如果你想加入我们的讨论群或者希望要更详细的资料,文末加入。 喜欢本文记得收藏、关注、点赞 文章目…

力扣精选算法100道—— 连续数组(前缀和专题)

连续数组&#xff08;前缀和专题&#xff09; 目录 &#x1f6a9;了解题意 &#x1f6a9;算法原理 ❗为什么hash设置成<0,-1>键值对 ❗与和为K的子数组比较hash的键值对 &#x1f6a9;代码实现 &#x1f6a9;了解题意 我们看到给定数组里面只有0和1&#xff0c;我们…

植物生长调节剂行业调研:预计2029年将达到1.2亿美元

未来增长的重点势必在以中国为代表的亚太地区。尤其在我国农业现代化、无人化发展需求下&#xff0c;提升种植的效率和品质是必然需求&#xff0c;我国市场规模增速也将高于全球平均水平。植物生长调节剂的应用具有成本低、收效快、效益高、节省劳动力的优点&#xff0c;不仅对…

Elasticsearch:使用 LangChain 文档拆分器进行文档分块

使用 Elasticsearch 嵌套密集向量支持 这个交互式笔记本将&#xff1a; 将模型 “sentence-transformers__all-minilm-l6-v2” 从 Hugging Face 加载到 Elasticsearch ML Node 中使用 LangChain 分割器将段落分块成句子&#xff0c;并使用嵌套密集向量将它们索引到 Elasticse…

fghbbbbbbbbbb

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 磁盘满的本质分析 专栏&#xff1a;《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具…

LeetCode 二叉树/n叉树的解题思路

二叉树 二叉树特点是每个节点最多只能有两棵子树&#xff0c;且有左右之分二叉树的数据结构如下&#xff1a; public class TreeNode {//节点的值int val;//左子树TreeNode left;//右子树TreeNode right;TreeNode(int x) { val x; } }树节点的初始化&#xff1a; int val1;T…

Flink Checkpoint过程

Checkpoint 使用了 Chandy-Lamport 算法 流程 1. 正常流式处理&#xff08;尚未Checkpoint&#xff09; 如下图&#xff0c;Topic 有两个分区&#xff0c;并行度也为 2&#xff0c;根据奇偶数 我们假设任务从 Kafka 的某个 Topic 中读取数据&#xff0c;该Topic 有 2 个 Pa…