日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

troubleshoot之:用control+break解决线程死锁问题

發布時間:2024/9/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 troubleshoot之:用control+break解决线程死锁问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介:如果我們在程序中遇到線程死鎖的時候,該怎么去解決呢? 本文將會從一個實際的例子出發,一步一步的揭開java問題解決的面紗。

簡介

如果我們在程序中遇到線程死鎖的時候,該怎么去解決呢?

本文將會從一個實際的例子出發,一步一步的揭開java問題解決的面紗。

死鎖的代碼

寫過java多線程程序的人應該都知道,多線程中一個很重要的事情就是狀態的同步,但是在狀態同步的過程中,一不小心就有可能會導致死鎖的問題。

一個最簡單的死鎖情況就是thread1占有資源1,然后又要去獲取資源2. 而thread2占有資源2,又要去獲取資源1的情況。

舉個具體的例子:

public class TestDeadLock {public static Object lock1= new Object();public static Object lock2= new Object();public static void main(String[] args) {Runnable runnable1= ()-> {System.out.println("in lock1");synchronized(lock1){System.out.println("Lock1 lock obj1");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}synchronized(lock2){System.out.println("Lock1 lock obj2");}}};Runnable runnable2= ()-> {System.out.println("in lock2");synchronized(lock2){System.out.println("Lock2 lock obj2");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}synchronized(lock1){System.out.println("Lock2 lock obj1");}}};Thread a = new Thread(runnable1);Thread b = new Thread(runnable2);a.start();b.start();} }

我們運行上面的代碼:

in lock1 Lock1 lock obj1 in lock2 Lock2 lock obj2

發送了鎖循環等待的情況,程序執行不下去了,發送了死鎖。

control+break命令

在代碼很簡單的情況下,我們很容易就能分析出來死鎖的原因,但是如果是在一個非常龐大的線上項目的時候,分析代碼就沒有那么容易了。

怎么做呢?

今天教給大家一個方法,使用control+break命令。

control+break在linux表示的是Control+backslash,而在Windows下面就是Control+Break按鈕。

當然,還有一個更加通用的就是使用:

kill -QUIT pid命令。

我們用jps命令獲取到執行java程序的進程id,然后執行kill -QUIT命令。

執行完畢,我們會發現運行的java進程會輸出一些額外的日志,這些額外的日志就是我們找出死鎖的關鍵因素。

注意,這個kill命令并不會終止程序的運行。

輸出的內容比較多,我們一部分一部分的講解。

Full thread dump

日志的第一部分就是Full thread dump,包含了JVM中的所有線程的狀態信息。

我們看一下我們代碼中的兩個關鍵線程信息:

"Thread-0" #13 prio=5 os_prio=31 cpu=4.86ms elapsed=230.16s tid=0x00007fc926061800 nid=0x6403 waiting for monitor entry [0x0000700008d6a000]java.lang.Thread.State: BLOCKED (on object monitor)at com.flydean.TestDeadLock.lambda$main$0(TestDeadLock.java:21)- waiting to lock <0x0000000787e868f0> (a java.lang.Object)- locked <0x0000000787e868e0> (a java.lang.Object)at com.flydean.TestDeadLock$$Lambda$14/0x0000000800b69840.run(Unknown Source)at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)"Thread-1" #14 prio=5 os_prio=31 cpu=4.32ms elapsed=230.16s tid=0x00007fc924869800 nid=0x6603 waiting for monitor entry [0x0000700008e6d000]java.lang.Thread.State: BLOCKED (on object monitor)at com.flydean.TestDeadLock.lambda$main$1(TestDeadLock.java:36)- waiting to lock <0x0000000787e868e0> (a java.lang.Object)- locked <0x0000000787e868f0> (a java.lang.Object)at com.flydean.TestDeadLock$$Lambda$15/0x0000000800b69c40.run(Unknown Source)at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)

上面的輸出列出了線程名字,線程的優先級,cpu時間,是否是daemon線程,線程ID,線程狀態等有用的信息。

看到上面的輸出,我們看到兩個線程都是處于BLOCKED狀態,都在等待object monitor。

還記得線程的幾個狀態嗎? 我們再來復習一下。

死鎖檢測

接下來的部分就是我們最關心的死鎖檢測了。

Found one Java-level deadlock: ============================= "Thread-0":waiting to lock monitor 0x00007fc926807e00 (object 0x0000000787e868f0, a java.lang.Object),which is held by "Thread-1""Thread-1":waiting to lock monitor 0x00007fc926807f00 (object 0x0000000787e868e0, a java.lang.Object),which is held by "Thread-0"Java stack information for the threads listed above: =================================================== "Thread-0":at com.flydean.TestDeadLock.lambda$main$0(TestDeadLock.java:21)- waiting to lock <0x0000000787e868f0> (a java.lang.Object)- locked <0x0000000787e868e0> (a java.lang.Object)at com.flydean.TestDeadLock$$Lambda$14/0x0000000800b69840.run(Unknown Source)at java.lang.Thread.run(java.base@14.0.1/Thread.java:832) "Thread-1":at com.flydean.TestDeadLock.lambda$main$1(TestDeadLock.java:36)- waiting to lock <0x0000000787e868e0> (a java.lang.Object)- locked <0x0000000787e868f0> (a java.lang.Object)at com.flydean.TestDeadLock$$Lambda$15/0x0000000800b69c40.run(Unknown Source)at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)Found 1 deadlock.

上面的日志我們可以很明顯的看出來,兩個線程分別獲得了對方需要的鎖,所以導致了死鎖。

同時還詳細的列出了thread stack的信息,供我們分析。

如果我們添加了參數-XX:+PrintConcurrentLocks,還會輸出各個線程的獲得的concurrent lock信息。

Heap信息

最后一部分是Heap的統計信息:

Heapgarbage-first heap total 133120K, used 3888K [0x0000000780000000, 0x0000000800000000)region size 1024K, 4 young (4096K), 0 survivors (0K)Metaspace used 1122K, capacity 4569K, committed 4864K, reserved 1056768Kclass space used 108K, capacity 412K, committed 512K, reserved 1048576K

如果我們添加了-XX:+PrintClassHistogram命令,還可以額外的輸出class直方圖統計信息。

總結

上面就是使用Control+Break命令來分析java死鎖問題的具體例子,希望大家能夠喜歡。

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jvm-diagnostic-control-break/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等著您!

原文鏈接:https://developer.aliyun.com/article/769880?

版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。

總結

以上是生活随笔為你收集整理的troubleshoot之:用control+break解决线程死锁问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。