JVM线程分析详解

java线程状态:
在这里插入图片描述

  1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

Java Monitor原理:
Monitor 是Java中用以实现线程之间的互斥与协作的主要手段,可以看成是对象或者Class的锁。每一个对象有且仅有一个monitor。Java 的 Object 类本身就是监视者对象,Java 对于 Monitor Object 模式做了内建的支持。
Object 类本身就是监视者对象!
每个 Object 都带了一把看不见的锁,通常叫 内部锁/Monitor 锁/Instrinsic Lock, 这把锁就是 监控锁。
synchronized 关键字修饰方法和代码块就是 同步方法
wait()/notify()/notifyAll() 方法构成监控条件(Monitor Condition)
在这里插入图片描述
线程和Monitor之间关系:
一个Monitor在某个时刻,只能被一个线程拥有,该线程就是Active Thread,
而其它线程都是Waiting Thread,分别在两个队列Entry Set和Wait Set里面等候。
在Entry Set中等待的线程状态是Waiting for monitor entry,
在Wait Set中等待的线程状态是in Object.wait()。

线程进入同步方法中:
为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner)
拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。
其他线程调用 notify() / notifyAll() 接口唤醒等待集合中的线程,这些等待的线程需要重新获取监视锁后才能执行 wait() 之后的代码。
同步方法执行完毕了,线程退出临界区,并释放监视锁。

进入区(Entrt Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。
拥有者(The Owner):表示某一线程成功竞争到对象锁。
等待区(Wait Set):表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。

线程调用修饰:
表示线程在方法调用时,额外的重要的操作,一般出现在线程内容中,用来协助分析线程的状态。
locked <对象地址> 对象名: 表示当前线程通过synchronized关键字成功获取到了目标对象的监视器,拥有了在临界区操作的权限,状态一般为runnable。注意对象锁是可重入的,所以这里有2次锁住了同一个对象。
waiting to lock <对象地址> 对象名:
表示当前线程未能通过synchronized关键字获取到目标对象的监视器,状态一般为blocked。
waiting on<对象地址> 对象名:
表示当前线程通过synchronized关键字成功获取到了目标对象的监视器,但调用了wait方法,进入对象的等待区等待。在调用栈顶出现,线程状态为WAITING或TIMED_WATING。
parking to wait for <对象地址> 对象名:
park是基本的线程阻塞原语,不通过监视器在对象上阻塞。随concurrent包会出现的新的机制,与synchronized体系不同,具体介绍可以看stackoverflow上的回答传送门。

系统线程状态:
出现在线程信息第一行的末尾。
deadlock:死锁线程
runnable:表示线程运行中或I/O等待,线程状态一般为RUNNABLE。
in Object.wait():进入临界区之后,又调用了java.lang.Object.wait()方法等待,jvm线程状态一般为WAITING或TIMED_WAITING。
waiting for monitor entry:在等待进入一个临界区,线程状态一般状态为BLOCKED。
waiting on condition:线程正处于等待资源或等待某个条件的发生,具体的原因需要结合下面堆栈信息进行分析。
(1)如果堆栈信息明确是应用代码,则证明该线程正在等待资源,一般是大量读取某种资源且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取,或者正在等待其他线程的执行等。
(2)如果发现有大量的线程都正处于这种状态,并且堆栈信息中得知正等待网络读写,这是可能因为网络阻塞导致线程无法执行。
(3)还有一种常见的情况是该线程在sleep,等待sleep的时间到了,将被唤醒。

JVM线程状态:
java.lang.Thread.State: RUNNABLE 线程运行中或I/O等待 方法调用-无
java.lang.Thread.State: BLOCKED (on object monitor) 等待进入一个临界区 方法调用-synchronized
java.lang.Thread.State: TIMED_WAITING (parking) 线程等待唤醒,并且设置等待时长 方法调用-LockSupport.parkNanos(等待时长)、LockSupport.parkUntil(等待时长)
java.lang.Thread.State: TIMED_WAITING (sleeping) 线程等待唤醒,并且设置等待时长 方法调用-Thread.sleep(等待时长),Thread.join(等待时长)
java.lang.Thread.State: TIMED_WAITING (on object monitor) 线程在等待唤醒,并且设置等待时长 方法调用-Object.wait(等待时长)
java.lang.Thread.State: WAITING (parking) 线程等待唤醒,没有设置等待时长 方法调用-LockSupport.park()
java.lang.Thread.State: WAITING (on object monitor) 线程等待唤醒,并且没有设置等待时长 方法调用-Object.wait()
java.lang.Thread.State: WAITING (on object monitor) 线程等待唤醒,没有设置等待时长 方法调用-Thread.join()

jvm日志分析:
“ForkJoinPool.commonPool-worker-52”{线程名} #5688{线程ID} daemon prio=5{线程的优先级,取值范围为[1-10],默认为 5,数值越低越有优先} os_prio=0{线程在操作系统中的优先级} tid=0x00007f31eb3f3800 nid=0xa8ec{Native thread ID,本地操作系统相关的线程id,对应JVM 虚拟机中线程映射在操作系统中的线程编号。(这个nid就是我们用top -Hp pid 查看到的线程号,不过要用printf "%x\n"转换一下进制)} waiting on condition [0x00007f31944d0000]{系统线程状态}
java.lang.Thread.State: WAITING (parking){JVM线程状态}
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000004706e6598> (a java.util.concurrent.ForkJoinPool)
at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Locked ownable synchronizers:
- None

常见问题:
1)锁争用
如果出现大量的锁争用,可能是线程阻塞了!
#48线程获得了 <0x000000046b9b6078>对象的锁,进入了临界区;#49无法获取到锁,停留在Entry Set中,输出waiting to lock <0x000000046b9b6078>。
“hiveserver2-web-49-acceptor-2@23302924-ServerConnector@6d6d480c{HTTP/1.1,[http/1.1]}{0.0.0.0:10002}” #49 daemon prio=3 os_prio=0 tid=0x00007f31eaf33000 nid=0x6306 waiting for monitor entry [0x00007f31a3dfc000]
java.lang.Thread.State: BLOCKED (on object monitor) --JVM线程状态
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:234)
- waiting to lock <0x000000046b9b6078> (a java.lang.Object)
at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:397)
at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:601)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:748)

Locked ownable synchronizers:
- None
“hiveserver2-web-48-acceptor-1@580fe4f0-ServerConnector@6d6d480c{HTTP/1.1,[http/1.1]}{0.0.0.0:10002}” #48 daemon prio=3 os_prio=0 tid=0x00007f31eaf31800 nid=0x6305 runnable [0x00007f31a3efd000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x000000046b9b6078> (a java.lang.Object)
at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:397)
at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:601)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:748)

Locked ownable synchronizers:
- None

2)死锁
如果两个线程相互都被对方的线程锁锁住,这样就造成了死锁。
Thread1获取了<0x00000000d8251168>锁,等待<0x00000000d8251198>锁;Thread2获取了<0x00000000d8251198>锁,等待<0x00000000d8251168>锁。导致死锁!
“Thread2” daemon prio=5 tid=0x00007f1d3825f800 nid=0x2142 waiting for monitor entry [0x00007f1d16eeb000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.jvm.study.threaddump.deadlock.DeadLockMock$2.run(DeadLockMock.java:31)
- waiting to lock <0x00000000d8251168> (a java.lang.String)
- locked <0x00000000d8251198> (a java.lang.String)
“Thread1” daemon prio=5 tid=0x00007f1d3825e000 nid=0x2141 waiting for monitor entry [0x00007f1d16fec000]
ava.lang.Thread.State: BLOCKED (on object monitor)
at com.jvm.study.threaddump.deadlock.DeadLockMock$1.run(DeadLockMock.java:16)
- waiting to lock <0x00000000d8251198> (a java.lang.String)
- locked <0x00000000d8251168> (a java.lang.String)

3)等待区等待
JVM线程的状态是java.lang.Thread.State: TIMED_WAITING (on object monitor),线程调用了java.lang.Object.wait(Native Method)方法而进入了等待状态。
"Wait Set"中等待的线程状态就是 in Object.wait();
当线程获得了Monitor进入临界区之后,如果发现线程继续运行的条件没有满足,它就调用对象(通常是被synchronized的对象)的wait()方法,放弃了Monitor,进入"Wait Set"队列中。
只有当别的线程在该对象上调用了notify()或notifyAll()方法, “Wait Set” 队列中线程才得到机会去竞争,但是只有一个线程获得对象的 Monitor,从而恢复到运行态。
“IPC Client (2108708444) connection to IT-CDH-Node02/10.11.16.36:8020 from hive” #5681 daemon prio=5 os_prio=0 tid=0x00007f31ccf4a000 nid=0xa8e4 in Object.wait() [0x00007f319aa33000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.apache.hadoop.ipc.ClientConnection.waitForWork(Client.java:1017)
- locked <0x000000042b52dbf0> (a org.apache.hadoop.ipc.Client$Connection)
at org.apache.hadoop.ipc.ClientConnection.run(Client.java:1061)

Locked ownable synchronizers:
- None

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

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

相关文章

deepseek+mermaid【自动生成流程图】

成果&#xff1a; 第一步打开deepseek官网(或百度版&#xff08;更快一点&#xff09;)&#xff1a; 百度AI搜索 - 办公学习一站解决 第二步&#xff0c;生成对应的Mermaid流程图&#xff1a; 丢给deepseek代码&#xff0c;或题目要求 生成mermaid代码 第三步将代码复制到me…

C大调中的A4=440Hz:音乐、物理与认知的交响

引言&#xff1a; 在音乐的世界里&#xff0c;每个音符都是一个独特的存在&#xff0c;它们按照特定的规则和比例相互交织&#xff0c;创造出和谐的旋律。在众多音符中&#xff0c;A4440Hz作为一个国际标准音高&#xff0c;它在C大调中扮演着“la”的角色。这一看似简单的对应关…

ASPNET Core笔试题 【面试宝典】

文章目录 一、如何在ASP.NET Core中激活Session功能&#xff1f;二、什么是中间件&#xff1f;三、ApplicationBuilder的Use和Run方法有什么区别&#xff1f;四、如何使TagHelper在元素这一层上失效&#xff1f;五、什么是ASP.NET Core&#xff1f;六、ASP.NET Core中AOP的支持…

使用DeepSeek实现自动化编程:类的自动生成

目录 简述 1. 通过注释生成C类 1.1 模糊生成 1.2 把控细节&#xff0c;让结果更精准 1.3 让DeepSeek自动生成代码 2. 验证DeepSeek自动生成的代码 2.1 安装SQLite命令行工具 2.2 验证DeepSeek代码 3. 测试代码下载 简述 在现代软件开发中&#xff0c;自动化编程工具如…

MapReduce编程模型

MapReduce编程模型 理解MapReduce编程模型独立完成一个MapReduce程序并运行成功了解MapReduce工程流程掌握并描述出shuffle全过程&#xff08;面试&#xff09;独立编写课堂及作业中的MR程序理解并解决数据倾斜 1. MapReduce编程模型 Hadoop架构图 Hadoop由HDFS分布式存储、M…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.3.2Kibana可视化初探

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 10分钟快速部署Kibana可视化平台1. Kibana与Elasticsearch关系解析1.1 架构关系示意图1.2 核心功能矩阵 2. 系统环境预检2.1 硬件资源配置2.2 软件依赖清单 3. Docker快速部…

基于YOLO11深度学习的遥感视角农田检测与分割系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

Redis7——进阶篇(一)

前言&#xff1a;此篇文章系本人学习过程中记录下来的笔记&#xff0c;里面难免会有不少欠缺的地方&#xff0c;诚心期待大家多多给予指教。 基础篇&#xff1a; Redis&#xff08;一&#xff09;Redis&#xff08;二&#xff09;Redis&#xff08;三&#xff09;Redis&#x…

ST-LINK端口连接失败,启动GDB server失败的问题处理方法,有效

目录 1. 问题描述2. 解决办法2.1 后台关闭2.2 后台关闭无法找到ST进程或者关闭后未解决 1. 问题描述 报错&#xff1a; Failed to bind to port 61235, error code -1: No error Failure starting SWV server on TCP port: 61235 Failed to bind to port 61234, error code -1…

Helix——Figure 02发布的通用人形机器人控制VLA:不用微调即可做多个任务的快与慢双系统,让两个机器人协作干活(含清华HiRT详解)

前言 过去一周&#xff0c;我花了很大的心思、力气&#xff0c;把deepseek的GRPO、MLA算法的代码解析通透&#xff0c;比如GRPO与PPO的详细对比&#xff0c;再比如MLA中&#xff0c;图片 公式 代码的一一对应&#xff0c;详见此专栏《火爆全球的DeepSeek系列模型》 2.20日晚&…

性能测试测试策略制定|知名软件测评机构经验分享

随着互联网产品的普及&#xff0c;产品面对的用户量级也越来越大&#xff0c;能抗住指数级增长的瞬间访问量以及交易量是保障购物体验是否顺畅的至关重要的一环&#xff0c;而我们的性能测试恰恰也是为此而存在的。 性能测试是什么呢&#xff1f;性能测试要怎么测呢&#xff1f…

BigDecimal 为什么可以不丢失精度?

本文已收录至Java面试网站&#xff1a;https://topjavaer.cn 大家好&#xff0c;今天咱们来聊聊 Java 中的 BigDecimal。在金融领域&#xff0c;数据的精确性相当重要&#xff0c;一个小数点的误差可能就意味着几百万甚至几千万的损失。而 BigDecimal 就是专门用来解决这种高精…

杰发科技AC7801——滴答定时器获取时间戳

1. 滴答定时器 杰发科技7801内部有一个滴答定时器&#xff0c;该定时器是M0核自带的&#xff0c;因此可以直接用该定时器来获取时间戳。 同样&#xff0c;7803也可以使用该方式获取时间戳。 2. 滴答定时器原理 SysTick是一个24位的递减计数器&#xff0c;它从预设的重装载值…

Cursor+pycharm接入Codeuim(免费版),Tab自动补全功能平替

如题&#xff0c;笔者在Cursor中使用pycharm写python程序&#xff0c;试用期到了Tab自动补全功能就不能用了&#xff0c;安装Codeuim插件可以代替这个功能。步骤如下&#xff1a; 1. 在应用商店中搜索扩展Codeuim&#xff0c;下载安装 2. 安装完成后左下角会弹出提示框&#x…

第十四届蓝桥杯大赛软件赛国赛C/C++大学C组

A 【跑步计划——日期问题】-CSDN博客 B 【残缺的数字】-CSDN博客 C 题目 代码 #include <bits/stdc.h> using namespace std;void change(int &x) {int sum 0, t x;while(t){sum t % 10;t / 10;}x - sum; } int main() {int n;cin >> n;int ans 0;…

lua基础语法学习

lua基础语法学习 文章目录 lua基础语法学习1. 基础2. 输入输出3. 分支结构与循环结构4. 函数5. 元表与元方法6. 面向对象 1. 基础 注释 --单行注释--[[ 多行注释 --]]标识符 标识符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上 0 个或多个字母&#xff0c;下划线&…

Android APK组成编译打包流程详解

Android APK&#xff08;Android Package&#xff09;是 Android 应用的安装包文件&#xff0c;其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明&#xff1a; 一、APK 的组成 APK 是一个 ZIP 格式的压缩包&#xff0c;包含应用运行所需的所有文件。解压后主要包含以…

【MySQL篇】数据库基础

目录 1&#xff0c;什么是数据库&#xff1f; 2&#xff0c;主流数据库 3&#xff0c;MySQL介绍 1&#xff0c;MySQL架构 2&#xff0c;SQL分类 3&#xff0c;MySQL存储引擎 1&#xff0c;什么是数据库&#xff1f; 数据库&#xff08;Database&#xff0c;简称DB&#xf…

卷积神经网络(cnn,类似lenet-1,八)

我们第一层用卷积核&#xff0c;前面已经成功&#xff0c;现在我们用两层卷积核&#xff1a; 结构如下&#xff0c;是不是很想lenet-1&#xff0c;其实我们24年就实现了sigmoid版本的&#xff1a; cnn突破九&#xff08;我们的五层卷积核bpnet网络就是lenet-1&#xff09;-CS…

uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法

需求&#xff1a; 如下图&#xff0c;要实现左图的样式&#xff0c;先实现框架&#xff0c;文字到时候 往里填就行了&#xff0c;原来的解决方案是想用css,html来实现&#xff0c;发现实现起来蛮麻烦的。我也没找到合适的实现方法&#xff0c;最后换使用canvas来实现&#xff…