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

news2024/11/17 10:25:50

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.coloradmin.cn/o/1438381.html

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

相关文章

【Spring基础】从0开始学习Spring(2)

前言 在上篇文章,我已经讲了Spring中最核心的知识点:IoC(控制反转)以及DI(依赖注入)。这篇文章,我将讲一下关于Spring框架中的其它比较琐碎但是又还是挺重要的知识点,因此&#xff…

Excel——有效性、二级菜单联动

一、录入规范数据 1.手动输入序列录入有效性信息 选择需要录入有效性的所有单元格 选择【数据】——【有效性】——【有效性】 在【允许】输入的值之间选择【序列】 在【序列】输入框中输入想要选择的值,中间用逗号(必须是英文逗号)隔开 。…

[C/C++] -- Boost库、Muduo库编译安装使用

1.Muduo库 Muduo 是一个基于 C11 的高性能网络库,其核心是事件驱动、非阻塞 I/O、线程池等技术,以实现高并发、高性能的网络通信。Muduo 库主要由陈硕先生开发维护,已经成为 C 服务器程序员的常用工具之一。 Muduo 库的主要特点&#xff1a…

NLP_循环神经网络(RNN)

文章目录 RNN结构RNN实战RNN小结 RNN结构 NPLM 在处理长序列时会面临一些挑战。首先,由于它仍然是基于词的模型,因此在处理稀有词汇或者词汇表外的词汇时效果不佳。其次,NPLM不能很好地处理长距离依赖关系。而上面这两个局限,恰恰…

Python进阶--爬取下载人生格言(基于格言网的Python3爬虫)

目录 一、此处需要安装第三方库: 二、抓包分析及Python代码 1、打开人生格言网(人生格言-人生格言大全_格言网)进行抓包分析 2、请求模块的代码 3、抓包分析人生格言界面 4、获取各种类型的人生格言链接 5、获取下一页的链接 6、获取人生格言的…

基于Java (spring-boot)的酒店管理系统

一、项目介绍 本系统的使用者一共有酒店管理员和用户这两种角色: 1、酒店管理员功能: 登录:管理员可以通过登录功能进入系统,确保只有授权人员可以访问系统。 用户管理:管理员可以添加、编辑和删除酒店的用户,包括前…

【React】如何使antd禁用状态的表单输入组件响应点击事件?

最近遇到一个需求&#xff0c;需要在<Input.textarea>组件中&#xff0c;设置属性disabled为true&#xff0c;使textarea响应点击事件&#xff0c;但直接绑定onClick并不会在禁用状态下被响应。 解决方法1 之后尝试了很多方法&#xff0c;比如设置csspointer-events:no…

python30-Python的运算符结合性和优先级

1&#xff09;所有的数学运算都是从左向右进行的&#xff0c;Python 语言中的大部分运算符也是从左向右结合的&#xff0c;只有单目运算符、赋值运算符和三目运算符例外&#xff0c;它们是从右向左结合的&#xff0c;也就是说&#xff0c;它们是从右向左运算的。 2&#xff09…

01动力云客之环境准备+前端Vite搭建VUE项目入门+引入Element PLUS

1. 技术选型 前端&#xff1a;Html、CSS、JavaScript、Vue、Axios、Element Plus 后端&#xff1a;Spring Boot、Spring Security、MyBatis、MySQL、Redis 相关组件&#xff1a;HiKariCP&#xff08;Spring Boot默认数据库连接池&#xff09;、Spring-Data-Redis&#xff08;S…

JVM Java虚拟机入门指南

文章目录 为什么学习JVMJVM的执行流程JVM的组成部分类加载运行时数据区本地方法接口执行引擎 垃圾回收什么样的对象是垃圾呢内存溢出和内存泄漏定位垃圾的方法对象的finalization机制垃圾回收算法分代回收垃圾回收器 JVM调优参数JVM调优工具Java内存泄漏排查思路CPU飙高排查方案…

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

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

【JMeter】使用技巧

在这此对新版本jmeter的学习温习的过程&#xff0c;发现了一些以前不知道的功能&#xff0c;所以&#xff0c;整理出来与大分享。本文内容如下。 如何使用英文界面的jmeter如何使用镜像服务器Jmeter分布式测试启动Debug 日志记录搜索功能线程之间传递变量 如何使用英文界面的…

VMware虚拟机清理瘦身

用了一段时间VMware虚拟机之后&#xff0c;发现内存越来越小&#xff0c;也没装什么软件。。。 1.查询磁盘空间分布 虚拟机中磁盘空间查询 先看一下哪些地方占用的空间大&#xff0c;进行排查。 2.排查VMware复制文件产生的缓存路径 VMware复制文件有一个特点&#xff0c;以…

4、ChatGPT 无法完成的 5 项编码任务

ChatGPT 无法完成的 5 项编码任务 这是 ChatGPT 不能做的事情的一个清单,但这并非详尽无遗。ChatGPT 可以从头开始生成相当不错的代码,但是它不能取代你的工作。 我喜欢将 ChatGPT 视为 StackOverflow 的更智能版本。非常有帮助,但不会很快取代专业人士。当 ChatGPT 问世时…

docker常用10条容器操作命令

Docker 中一些常用的容器操作命令&#xff0c;我们可以根据需要使用这些命令来管理和操作 Docker 容器。我们这次以Hell-world这个镜像为例来说明&#xff1a; 1. docker pull hello-world #拉取hell-world镜像 2. docker images # 查看本地拉取的镜像 3. docker run hello…

VM 虚拟机和容器技术之间有什么区别?

随着云计算技术的不断发展&#xff0c;虚拟机和容器技术作为两种常见的虚拟化技术&#xff0c;被广泛应用于云计算领域。虽然虚拟机和容器技术都是虚拟化技术&#xff0c;但它们之间存在一些重要的区别。本文将详细介绍虚拟机和容器技术的区别&#xff0c;以便读者更好地了解这…

Qt信号和槽机制(什么是信号和槽,connect函数的形式,按钮的常用信号,QWidget的常用槽,自定义槽函数案例 点击按钮,输出文本)

一.什么是信号和槽 信号槽式Qt中的一个很重要的机制。信号槽实际上是观察者模式,当发生了感兴趣的事件&#xff0c;某一个操作就会被自动触发。当某个事件发生之后&#xff0c;比如按钮检测到自己被点击了一下&#xff0c;它就会发出一个信号。这种发出类似广播。如果有对象对…

HubSpot x 小红书:MessageBox打破数据壁垒

在当今数字营销的快速发展环境中&#xff0c;企业面临着将多个系统平台整合在一起以实现更有效营销策略的挑战。然而&#xff0c;随着技术的不断进步&#xff0c;诸如MessageBox这样的工具正在成为解决这一挑战的关键。MessageBox作为一种能够对接多个系统平台的工具&#xff0…

进程间通信(4):消息队列

先进先出&#xff0c;保证信息的有序性。 函数&#xff1a;msgget(搭配ftok)、msgsnd、msgrcv、msgctl 实现流程&#xff1a; 1、创建消息队列IPC对象 msgget 2、通信(内置函数&#xff1a;msgsnd、msgrcv) 3、删除消息队列IPC对象 msgctl write.c /* * 文件名称&…

浅谈交换原理(3)——交换网络

一、基本概念 交换网络是由若干个交换单元按照一定的拓扑结构和控制方式构成的网络。交换网络的三个基本要素是&#xff1a;交换单元、不同交换单元间的拓扑连接和控制方式。 1.1 单机交换网络与多级交换网络 交换网络按拓扑连接方式可分为&#xff1a;单级交换网络和多级交换网…