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.pswp.cn/diannao/72082.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72082.shtml
英文地址,請注明出處:http://en.pswp.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;是指一個用戶與服務器之間…