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

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理&#xff1a;检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目&#xff1a;RankRAG&#xff1a;Unifying Context Ranking…...

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南

Spring Boot 中实现 HTTPS 加密通信及常见问题排查指南 在金融行业安全审计中&#xff0c;未启用HTTPS的Web应用被列为高危漏洞。通过正确配置HTTPS&#xff0c;可将中间人攻击风险降低98%——本文将全面解析Spring Boot中HTTPS的实现方案与实战避坑指南。 一、HTTPS 核心原理与…...

比较数据迁移后MySQL数据库和PostgreSQL数据仓库中的表

设计一个MySQL数据库和PostgreSQL数据库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较两…...

设备健康管理的范式革命:中讯烛龙全链路智能守护系统

当工业设备的“亚健康”状态导致隐性产能损失高达23%时&#xff0c;中讯烛龙推出 ​​“感知-诊断-决策-闭环”四位一体解决方案&#xff0c;让设备全生命周期健康管理成为企业增长的隐形引擎。 一、行业痛点&#xff1a;传统运维的三大断层 1. 健康感知盲区 某风电场因无法捕…...

Fetch API 使用详解:Bearer Token 与 localStorage 实践

Fetch API&#xff1a;现代浏览器内置的用于发送 HTTP 请求的 API&#xff0c;Bearer Token&#xff1a;一种基于令牌的身份验证方案&#xff0c;常用于 JWT 认证&#xff0c;localStorage&#xff1a;浏览器提供的持久化存储方案&#xff0c;用于在客户端存储数据。 token是我…...

Redis常见使用场景解析

1. 数据库缓存 Redis 作为典型的 Key-Value 型内存数据库,数据缓存是其最广为人知的应用场景。使用 Redis 缓存数据操作简便,通常将序列化后的对象以 string 类型存储。但在实际应用中,需注意以下关键要点: Key 设计:必须确保不同对象的 Key 具有唯一性,且尽量缩短长度,…...