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.mzph.cn/diannao/72082.shtml

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

相关文章

android智能指针android::sp使用介绍

android::sp 是 Android 中的智能指针&#xff08;Smart Pointer&#xff09;的实现&#xff0c;用于管理对象的生命周期&#xff0c;避免手动管理内存泄漏等问题。它是 Android libutils 库中重要的一部分&#xff0c;常用于管理继承自 android::RefBase 的对象。 与标准库中…

spring整合mybatis详细步骤

spring整合mybatis的全部过程(整合方式一 &#xff1a;简单版) 1.在pom.xml中导入mybatis相应的jar包&#xff1a; (2) < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis</ artifactId > < version >3.5.3&…

2025年Linux主力系统选择指南:基于最新生态的深度解析(附2025年发行版对比速查表)

Linux发行版生态在2025年持续演进&#xff0c;既有经典系统的迭代升级&#xff0c;也有新兴项目的崛起。本文结合最新行业动态&#xff0c;从个人用户到企业场景&#xff0c;梳理主力系统选择策略&#xff0c;助你找到最适合的Linux发行版。 一、新手友好型&#xff1a;平滑过渡…

ai-2、机器学习之线性回归

机器学习之线性回归 1、机器学习2、线性回归2.1、梯度下降法 3、python下调用scikit-learn 1、机器学习 2、线性回归 ####所以y可以当成我们需要的结果&#xff0c;根据公式可以求的y一撇的值更小&#xff0c;所以更接近需要的结果&#xff0c;所以y一撇拟合性更好 2.1、梯度下…

Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存

Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 目录 Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 一、简单介绍 二、简单介绍 camera 三、安装 camera 四、简单案例实现 五、关键代码 一、简单…

【原创】Open WebUI 本地部署

使用官网的默认部署&#xff0c;遇到不少的问题。比如白屏问题&#xff0c;其实需要修改几个参数即可。 其实在部署的时候有不少参数 WEBUI_AUTH False ENABLE_OPENAI_API 0 PATH /usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin LANG C.UTF-8…

【造个轮子】使用Golang实现简易令牌桶算法

本文目录 1. 令牌桶算法2. 调用第三方库实现令牌桶3. 手撕令牌桶 前言&#xff1a;之前在Bluebell社区项目中&#xff0c;我们使用了开源的库来实现令牌桶限流&#xff0c;这次我们试着使用Go来手撕实现下令牌桶算法。 1. 令牌桶算法 为了防止网络拥塞&#xff0c;需要限制流…

C#开发的Base64编码及解码完整源码及注意事项

在软件开发时&#xff0c;经常用Base64编码和解码功能。本文介绍一个简单易用的Base64 编码和解码工具&#xff0c;顾名思义&#xff0c;就是简单快捷地进行 Base64 代码的解码或编码操作。您的数据可以轻松地编码为 Base64 编码&#xff0c;也可以解码为可读的格式。传输数据时…

【Linux第一弹】Linux基础指令(上)

目录 1.ls指令 1.1 ls使用实例 2.pwd指令 3.cd指令 3.1 cd使用实例 4.touch指令 4.1touch使用实例 5.mkdir指令 5.1mkdir使用实例 6.rmdir指令和rm指令 6.1 rmdir指令使用实例->: 6.2 rm指令使用实例 7.man指令 8.cp指令 8.1 cp 使用实例 9.mv指令 9.1mv使用…

RabbitMQ系列(七)基本概念之Channel

RabbitMQ 中的 Channel&#xff08;信道&#xff09; 是客户端与 RabbitMQ 服务器通信的虚拟会话通道&#xff0c;其核心作用在于优化资源利用并提升消息处理效率。以下是其核心机制与功能的详细解析&#xff1a; 一、Channel 的核心定义 虚拟通信链路 Channel 是建立在 TCP 连…

Zookeeper(80)Zookeeper的常见问题有哪些?

Zookeeper作为分布式系统的协调服务&#xff0c;常见的问题主要集中在配置、性能、连接管理、数据一致性和节点故障等方面。以下是一些常见问题及其详细解决方法和代码示例。 1. 配置问题 问题描述 配置不当可能导致 Zookeeper 集群无法正常启动或运行效率低下。 解决方法 …

如何管理路由器

一、管理路由器的必要性 1、需要修改拨号上网的密码。 2、需要修改WIFI的SSID名字和密码。 3、设置DHCP协议信息。 4、设置IP地址的过滤规则。 5、给某个设备连接设置网络限速。 二、常见的方式 (一)web网页方式 1、计算机用双绞线或者WIFI的方式连接路由器。 2、在计算机中打开…

linux vim 撤销 回退操作

在Linux的vim编辑器中&#xff0c;撤销和回退操作是非常基本的&#xff0c;但它们可以通过不同的方式实现&#xff0c;具体取决于你想要的精确效果。下面是一些常用的方法&#xff1a; 1. 撤销&#xff08;Undo&#xff09; 单个撤销&#xff1a; 你可以通过按下u键来撤销上一…

浅谈流媒体协议以及视频编解码

流媒体协议介绍 流媒体协议用于传输视频、音频等多媒体数据&#xff0c;确保数据流畅地传输到用户设备。常见的流媒体协议包括 RTMP、HLS、DASH、WebRTC 等&#xff0c;每种协议具有不同的特点和适用场景。 1. RTMP (Real-Time Messaging Protocol) 定义&#xff1a;由 Adob…

AF3 DataPipeline类process_multiseq_fasta 方法解读

AlphaFold3 data_pipeline 模块DataPipeline类的 process_multiseq_fasta 方法用于处理多序列 FASTA 文件,生成 AlphaFold3 结构预测所需的特征,适用于多链复合物的预测。它结合了 Minkyung Baek 在 Twitter 上提出的“AlphaFold-Gap”策略,即通过在多链 MSA 中插入固定长度…

图片爬取案例

修改前的代码 但是总显示“失败” 原因是 修改之后的代码 import requests import os from urllib.parse import unquote# 原始URL url https://cn.bing.com/images/search?viewdetailV2&ccidTnImuvQ0&id5AE65CE4BE05EE7A79A73EEFA37578E87AE19421&thidOIP.TnI…

使用自动化运维工具 Ansible 集中化管理服务器

一、概述 Ansible 是一款为类 Unix 系统开发的自由开源的配置和自动化工具 官方网站:https://www.ansible.com/ Ansible 成立于 2013 年,总部设在北卡罗来纳州达勒姆,联合创始人 ad Ziouani 和高级副总裁 Todd Barr都是红帽的老员工。Ansible 旗下的开源软件 Ansible 十分…

CMU15445(2023fall) Project #2 - Extendible Hash Index 匠心分析

胡未灭&#xff0c;鬓已秋&#xff0c;泪空流 此生谁料 心在天山 身老沧州 ——诉衷情 完整代码见&#xff1a; SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering determinati…

P1706 全排列问题

题目描述 按照字典序输出自然数 1 到 n 所有不重复的排列&#xff0c;即 n 的全排列&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n。 输出格式 由 1∼n 组成的所有不重复的数字序列&#xff0c;每行一个序列。 每个数字保留 5 个场宽。…

会话与会话管理:Cookie与Session的深度解析

一、什么是会话&#xff1f; 二、Cookie&#xff1a;客户端存储技术 1. Cookie的工作原理 2、在后端设置cookie 3、在前端设置cookie 三、浏览器开启了cookie禁用怎么办&#xff1f; 一、什么是会话&#xff1f; 会话&#xff08;Session&#xff09;是指一个用户与服务器之间…