当前位置: 首页 > 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;包括存储策略、告警策略、通知策略以及联动策略。这些策略都是通过专门的列表页面进行集…...

目前主流AI绘画工具排名,功能参数全对比

本文对2026年主流AI绘画工具进行功能维度的详细盘点&#xff0c;包括核心功能、技术参数、模型生态、价格等&#xff0c;供开发者和专业用户参考选型。一、主流AI绘画工具概览工具开发方核心技术部署方式访问方式MidjourneyMidjourney Inc.自研模型SaaS需海外访问Stable Diffus…...

中科院拒绝支付版面费的期刊名单!

中科院拒绝支付版面费的期刊名单来了&#xff0c;都是质量不错的期刊&#xff0c;总共34本。若没有足够预算的&#xff0c;注意避雷!√ 分布学科&#xff1a;医学23本生物学8本综合性期刊3本√ 分区和IF&#xff1a;中科院1-2区占比82.4%&#xff0c;IF>5分占比79.4%√ TOP期…...

DevSecOps平台建设之必备数据库MySQL

MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系统)应用软件之一。在本教程中&#xff0c;会让大家快速掌握 MySQL 的基本知识&#xff0c;并轻松使用 MySQL 数据库…...

Spring Boot 缓存机制与性能分析

Spring Boot 缓存机制与性能分析 在现代高并发应用中&#xff0c;缓存技术是提升系统性能的关键手段之一。Spring Boot作为Java生态中广泛使用的框架&#xff0c;提供了强大的缓存支持&#xff0c;能够显著减少数据库访问压力&#xff0c;优化响应速度。本文将深入探讨Spring …...

Nest-access-control核心组件解析:Decorator、Guard与Module的完美协作

Nest-access-control核心组件解析&#xff1a;Decorator、Guard与Module的完美协作 【免费下载链接】nest-access-control Role and Attribute based Access Control for Nestjs &#x1f510; 项目地址: https://gitcode.com/gh_mirrors/ne/nest-access-control Nest-a…...

180天打造180个网站:Jennifer Dewalt的自学编程传奇之旅

180天打造180个网站&#xff1a;Jennifer Dewalt的自学编程传奇之旅 【免费下载链接】jennifer_dewalt a.k.a. 180 Websites in 180 Days 项目地址: https://gitcode.com/gh_mirrors/je/jennifer_dewalt Jennifer Dewalt通过"180天180个网站"的挑战&#xff0…...

终极指南:Qwerty Learner代码重构案例如何提升legacy code的可维护性

终极指南&#xff1a;Qwerty Learner代码重构案例如何提升legacy code的可维护性 【免费下载链接】qwerty-learner 为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件 / Words learning and English muscle memory training software designed for keyboard workers 项目地址…...

FireRedASR-AED-L开源模型实战:对接LangChain构建语音增强型RAG系统

FireRedASR-AED-L开源模型实战&#xff1a;对接LangChain构建语音增强型RAG系统 1. 引言&#xff1a;当语音识别遇上智能检索 想象一下这个场景&#xff1a;你手头有一堆会议录音、客户访谈或课程讲座的音频文件。你想快速找到其中讨论“项目预算”或“技术架构”的具体片段。…...

第一批玩OpenClaw的人,已经开始清醒了

最近全网刷屏的龙虾OpenClaw&#xff0c;正在用 AI 智能体重构整个开发行业 ——导致基础Java岗位需求持续收缩。文末可免费领取龙虾Open Clawa超详细安装教程因而掌握“JavaAI”复合型能力的开发者&#xff0c;已成市场争抢的香饽饽。Spring AI的出现&#xff0c;打破Java程序…...

MCP SDK性能衰减真相:跨语言序列化耗时飙升370%的4个隐蔽根源及优化对照表

第一章&#xff1a;MCP跨语言SDK性能衰减问题全景认知MCP&#xff08;Microservice Communication Protocol&#xff09;跨语言SDK在多语言微服务协同场景中广泛部署&#xff0c;但实践中普遍观测到显著的性能衰减现象——相同逻辑在Go原生实现中耗时约0.8ms&#xff0c;而经Py…...