当前位置: 首页 > news >正文

java 线程执行原理,java线程在jvm中执行流程

java 线程执行原理,java线程在jvm中执行流程

从jvm视角看java线程执行过程

##首先thread.c注册jni函数

JNIEXPORT void JNICALL
Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
static JNINativeMethod methods[] = {{"start0",           "()V",        (void *)&JVM_StartThread},{"stop0",            "(" OBJ ")V", (void *)&JVM_StopThread},{"isAlive",          "()Z",        (void *)&JVM_IsThreadAlive},{"suspend0",         "()V",        (void *)&JVM_SuspendThread},{"resume0",          "()V",        (void *)&JVM_ResumeThread},{"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},{"yield",            "()V",        (void *)&JVM_Yield},{"sleep",            "(J)V",       (void *)&JVM_Sleep},{"currentThread",    "()" THD,     (void *)&JVM_CurrentThread},{"countStackFrames", "()I",        (void *)&JVM_CountStackFrames},{"interrupt0",       "()V",        (void *)&JVM_Interrupt},{"isInterrupted",    "(Z)Z",       (void *)&JVM_IsInterrupted},{"holdsLock",        "(" OBJ ")Z", (void *)&JVM_HoldsLock},{"getThreads",        "()[" THD,   (void *)&JVM_GetAllThreads},{"dumpThreads",      "([" THD ")[[" STE, (void *)&JVM_DumpThreads},{"setNativeName",    "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};

##java Thread.java类start0 调用jni native方法

private native void start0();

##start0 调用jvm.cpp执行JVM_StartThread方法

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))JVMWrapper("JVM_StartThread");JavaThread *native_thread = NULL;// We cannot hold the Threads_lock when we throw an exception,// due to rank ordering issues. Example:  we might need to grab the// Heap_lock while we construct the exception.bool throw_illegal_thread_state = false;// We must release the Threads_lock before we can post a jvmti event// in Thread::start.{// Ensure that the C++ Thread and OSThread structures aren't freed before// we operate.MutexLocker mu(Threads_lock);// Since JDK 5 the java.lang.Thread threadStatus is used to prevent// re-starting an already started thread, so we should usually find// that the JavaThread is null. However for a JNI attached thread// there is a small window between the Thread object being created// (with its JavaThread set) and the update to its threadStatus, so we// have to check for thisif (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {throw_illegal_thread_state = true;} else {// We could also check the stillborn flag to see if this thread was already stopped, but// for historical reasons we let the thread detect that itself when it starts runningjlong size =java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));// Allocate the C++ Thread structure and create the native thread.  The// stack size retrieved from java is 64-bit signed, but the constructor takes// size_t (an unsigned type), which may be 32 or 64-bit depending on the platform.//  - Avoid truncating on 32-bit platforms if size is greater than UINT_MAX.//  - Avoid passing negative values which would result in really large stacks.NOT_LP64(if (size > SIZE_MAX) size = SIZE_MAX;)size_t sz = size > 0 ? (size_t) size : 0;native_thread = new JavaThread(&thread_entry, sz);// At this point it may be possible that no osthread was created for the// JavaThread due to lack of memory. Check for this situation and throw// an exception if necessary. Eventually we may want to change this so// that we only grab the lock if the thread was created successfully -// then we can also do this check and throw the exception in the// JavaThread constructor.if (native_thread->osthread() != NULL) {// Note: the current thread is not being used within "prepare".native_thread->prepare(jthread);}}}if (throw_illegal_thread_state) {THROW(vmSymbols::java_lang_IllegalThreadStateException());}assert(native_thread != NULL, "Starting null thread?");if (native_thread->osthread() == NULL) {ResourceMark rm(thread);log_warning(os, thread)("Failed to start the native thread for java.lang.Thread \"%s\"",JavaThread::name_for(JNIHandles::resolve_non_null(jthread)));// No one should hold a reference to the 'native_thread'.native_thread->smr_delete();if (JvmtiExport::should_post_resource_exhausted()) {JvmtiExport::post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,os::native_thread_creation_failed_msg());}THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),os::native_thread_creation_failed_msg());}#if INCLUDE_JFRif (JfrRecorder::is_recording() && EventThreadStart::is_enabled() &&EventThreadStart::is_stacktrace_enabled()) {JfrThreadLocal* tl = native_thread->jfr_thread_local();// skip Thread.start() and Thread.start0()tl->set_cached_stack_trace_id(JfrStackTraceRepository::record(thread, 2));}
#endifThread::start(native_thread);JVM_END

##创建线程

native_thread = new JavaThread(&thread_entry, sz);

##系统调用创建线程 os::create_thread(this, thr_type, stack_sz);

ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);

JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :Thread() {initialize();_jni_attach_state = _not_attaching_via_jni;set_entry_point(entry_point);// Create the native thread itself.// %note runtime_23os::ThreadType thr_type = os::java_thread;thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :os::java_thread;os::create_thread(this, thr_type, stack_sz);// The _osthread may be NULL here because we ran out of memory (too many threads active).// We need to throw and OutOfMemoryError - however we cannot do this here because the caller// may hold a lock and all locks must be unlocked before throwing the exception (throwing// the exception consists of creating the exception object & initializing it, initialization// will leave the VM via a JavaCall and then all locks must be unlocked).//// The thread is still suspended when we reach here. Thread must be explicit started// by creator! Furthermore, the thread must also explicitly be added to the Threads list// by calling Threads:add. The reason why this is not done here, is because the thread// object must be fully initialized (take a look at JVM_Start)
}
bool os::create_thread(Thread* thread, ThreadType thr_type,size_t req_stack_size) {assert(thread->osthread() == NULL, "caller responsible");// Allocate the OSThread object.OSThread* osthread = new OSThread(NULL, NULL);if (osthread == NULL) {return false;}// Set the correct thread state.osthread->set_thread_type(thr_type);// Initial state is ALLOCATED but not INITIALIZEDosthread->set_state(ALLOCATED);thread->set_osthread(osthread);// Init thread attributes.pthread_attr_t attr;pthread_attr_init(&attr);guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");// Make sure we run in 1:1 kernel-user-thread mode.if (os::Aix::on_aix()) {guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???");guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???");}// Start in suspended state, and in os::thread_start, wake the thread up.guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");// Calculate stack size if it's not specified by caller.size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);// JDK-8187028: It was observed that on some configurations (4K backed thread stacks)// the real thread stack size may be smaller than the requested stack size, by as much as 64K.// This very much looks like a pthread lib error. As a workaround, increase the stack size// by 64K for small thread stacks (arbitrarily choosen to be < 4MB)if (stack_size < 4096 * K) {stack_size += 64 * K;}// On Aix, pthread_attr_setstacksize fails with huge values and leaves the// thread size in attr unchanged. If this is the minimal stack size as set// by pthread_attr_init this leads to crashes after thread creation. E.g. the// guard pages might not fit on the tiny stack created.int ret = pthread_attr_setstacksize(&attr, stack_size);if (ret != 0) {log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k",(thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "),stack_size / K);thread->set_osthread(NULL);delete osthread;return false;}// Save some cycles and a page by disabling OS guard pages where we have our own// VM guard pages (in java threads). For other threads, keep system default guard// pages in place.if (thr_type == java_thread || thr_type == compiler_thread) {ret = pthread_attr_setguardsize(&attr, 0);}ResourceMark rm;pthread_t tid = 0;if (ret == 0) {int limit = 3;do {ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);} while (ret == EAGAIN && limit-- > 0);}if (ret == 0) {char buf[64];log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));} else {char buf[64];log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%d=%s) for attributes: %s.",thread->name(), ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));// Log some OS information which might explain why creating the thread failed.log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());LogStream st(Log(os, thread)::info());os::Posix::print_rlimit_info(&st);os::print_memory_info(&st);}pthread_attr_destroy(&attr);if (ret != 0) {// Need to clean up stuff we've allocated so far.thread->set_osthread(NULL);delete osthread;return false;}// OSThread::thread_id is the pthread id.osthread->set_thread_id(tid);return true;
}

##通过函数回调thread_entry方法

native_thread = new JavaThread(&thread_entry, sz);

static void thread_entry(JavaThread* thread, TRAPS) {HandleMark hm(THREAD);Handle obj(THREAD, thread->threadObj());JavaValue result(T_VOID);JavaCalls::call_virtual(&result,obj,SystemDictionary::Thread_klass(),vmSymbols::run_method_name(),vmSymbols::void_method_signature(),THREAD);
}

##call_virtual 执行java run方法

相关文章:

java 线程执行原理,java线程在jvm中执行流程

java 线程执行原理&#xff0c;java线程在jvm中执行流程 从jvm视角看java线程执行过程 ##首先thread.c注册jni函数 JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls) {(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(…...

[Redis]基本全局命令

Redis存储方式介绍 在 Redis 中数据是以键值对的凡事存储的&#xff0c;键&#xff08;Key&#xff09;和值&#xff08;Value&#xff09;是基本的数据存储单元。以下是对 Redis 键值对的详细讲解&#xff1a; 键&#xff08;Key&#xff09;&#xff1a; 类型&#xff1a;…...

【Linux】- HBase集群部署 [19]

简介 apache HBase是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 和Redis一样&#xff0c;HBase是一款KeyValue型存储的数据库。 不过和Redis涉及方向不同 Redis设计为少量数据&#xff0c;超快检索HBase设计为海量数据&#xff0c;快速检索 HBase在大数据邻域…...

js如何遍历FormData的值

遍历FormData的值&#xff0c;一般有2种方法&#xff1a;forEach 和 for...of entries const data new FormData();data.append(aaa, 111); data.append(bbb, 222);// 方法1 data.forEach((value, key) > {console.log(key, value); }) 输出 aaa 111 和 bbb 222// 方法2 …...

【C语言】明析部分C语言内存函数

目录 1.memcpy 2.memmove 3.memset 4.memcmp 以下都是内存函数&#xff0c;作用单位均是字节 1.memcpy memcpy是C/C语言中的一个内存拷贝函数&#xff0c;其原型为&#xff1a; void* memcpy(void* dest, const void* src, size_t n);目标空间&#xff08;字节&#xff09…...

一阶数字高通滤波器

本文的主要内容包含一阶高通滤波器公式的推导和数字算法的实现以及编程和仿真 1 计算公式推导 1.1.2 算法实现及仿真 利用python实现的代码如下&#xff1a; import numpy as np # from scipy.signal import butter, lfilter, freqz import matplotlib.pyplot as plt #2pifW…...

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和锁,线程同步和条件变量,线程其他知识点

Linux多线程系列2: 模拟封装简易语言级线程库,线程互斥和互斥锁,线程同步和条件变量,线程其他知识点 1.前言 一.模拟C11线程库自己封装简易语言级线程库1.实现框架2.迅速把构造等等函数写完3.start和work1.尝试一2.尝试二3.最终版本4.给出代码 二.模拟实现多线程(为编写线程池做…...

VUE3-form表单保存附件与基本信息

element-ui代码 <el-dialog :title"上传附件" v-model"dialogAdds.visible" width"500px" append-to-body> <el-form-item label"唯一标识"> <dict-tag v-if"form.groupId" :options"unique_identifica…...

无线网络安全技术基础

无线网络安全技术基础 无线网络安全风险和隐患 随着无线网络技术广泛应用,其安全性越来越引起关注.无线网络的安全主要有访问控制和数据加密,访问控制保证机密数据只能由授权用户访问,而数据加密则要求发送的数据只能被授权用户所接受和使用。 无线网络在数据传输时以微波进…...

sheng的学习笔记-docker部署Greenplum

目录 docker安装gp数据库 mac版本 搭建gp数据库 连接数据库 windows版本 搭建gp数据库 连接数据库 docker安装gp数据库 mac版本 搭建gp数据库 打开终端&#xff0c;输入代码&#xff0c;查看版本 ocker search greenplum docker pull projectairws/greenplum docker…...

【投稿资讯】区块链会议CCF A -- SP 2025 截止6.6、11.14 附录用率

会议名称&#xff1a;46th IEEE Symposium on Security and Privacy( S&P&#xff09; CCF等级&#xff1a;CCF A类学术会议 类别&#xff1a;网络与信息安全 录用率&#xff1a;2023年 195/1147&#xff0c;2024年录用了17篇和区块链相关的论文 Topics of interest inc…...

C++哪些函数不能被声明为虚函数

在C中&#xff0c;某些函数不能被声明为虚函数。下面详细解释哪些函数不能被声明为虚函数&#xff0c;并通过代码示例进行说明。 C哪些函数不能被声明为虚函数 不能声明为虚函数的函数示例代码及解释一、构造函数不能是虚函数二、静态成员函数不能是虚函数三、友元函数不能是虚…...

vue中数据已经改变了,但是table里面内容没更新渲染!

解决方案&#xff1a; 给table或者el-table标签上添加一个动态key值&#xff0c;只要数据发生改变&#xff0c;key值变动一下即可 标签上&#xff1a; :key“timeStamp” 初始data&#xff1a;timeStamp:0, 更新数据&#xff1a;this.timeStamp 这样每次更新数据&#xff…...

头歌实践教学平台:Junit实训入门篇

第2关&#xff1a;Junit注解 任务描述 给出一个带有注解的Junit代码及其代码打印输出&#xff0c;要求学员修改注解位置&#xff0c;让输出结果变为逆序。 相关知识 Junit注解 Java注解&#xff08;(Annotation&#xff09;的使用方法是" 注解名" 。借助注解&a…...

matlab使用教程(80)—修改图形对象的透明度

1.更改图像、填充或曲面的透明度 此示例说明如何修改图像、填充或曲面的透明度。 1.1坐标区框中所有对象的透明度 透明度值称为 alpha 值。使用 alpha 函数设置当前坐标区范围内所有图像、填充或曲面对象的透明度。指定一个介于 0&#xff08;完全透明&#xff09;和 1&#x…...

mysql bin 日志转成sql

首先确定mysql binlog 服务开启 SHOW VARIABLES LIKE log_bin; 找到binlog日志 find / -name mysql-bin.* -type f 下载下来 本地找到mysql安装位置的bin目录 在窗口路径处直接输入cmd 执行 mysqlbinlog --no-defaults --base64-outputdecode-rows -v --start-datetime&…...

河南道路与桥梁乙级资质申请:注册证书与职称证书准备

在河南道路与桥梁乙级资质申请中&#xff0c;注册证书与职称证书的准备是不可或缺的环节。以下是关于如何准备这些证书的一些关键步骤和要点&#xff1a; 明确所需证书类型&#xff1a; 注册证书&#xff1a;这通常指的是相关专业的注册工程师证书&#xff0c;如注册土木工程师…...

3D工业视觉

前言 本文主要介绍3D视觉技术、工业领域的应用、市场格局等&#xff0c;主要技术包括激光三角测量、结构光、ToF、立体视觉。 一、核心内容 3D视觉技术满足工业领域更高精度、更高速度、更柔性化的需求&#xff0c;扩大工业自动化的场景。 2D视觉技术基于物体平面轮廓&#…...

使用auth_basic模块进行基础认证

在建立和维护Web服务器时&#xff0c;身份认证是一个至关重要的环节。Nginx作为一个高性能的Web服务器&#xff0c;支持许多认证方法&#xff0c;其中较为简单和常用的一种即是基础身份认证&#xff08;Basic Authentication&#xff09;&#xff0c;这需要借助auth_basic模块实…...

深度解析物联网平台:优化数据点位管理的实战策略

策略管理 策略&#xff0c;作为在物联网平台数据点位创建过程中可设定的规则&#xff0c;涵盖了多个重要方面&#xff0c;策略是在创建点位的时候&#xff0c;可以设置的规则&#xff0c;包括存储策略、告警策略、通知策略以及联动策略。这些策略都是通过专门的列表页面进行集…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...