溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java怎么通過(guò)jstack命令查詢(xún)?nèi)罩?/h1>
發(fā)布時(shí)間:2023-03-21 15:27:14 來(lái)源:億速云 閱讀:152 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“Java怎么通過(guò)jstack命令查詢(xún)?nèi)罩尽保瑑?nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Java怎么通過(guò)jstack命令查詢(xún)?nèi)罩尽蔽恼履軒椭蠹医鉀Q疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

1 首先要清楚線(xiàn)程的狀態(tài)

線(xiàn)程的狀態(tài)有: new、runnable、running、waiting、timed_waiting、blocked、dead

1.1 線(xiàn)程狀態(tài)變遷圖:

Java怎么通過(guò)jstack命令查詢(xún)?nèi)罩?></p><h4>1.2 各狀態(tài)說(shuō)明:</h4><p>New: 當(dāng)線(xiàn)程對(duì)象創(chuàng)建時(shí)存在的狀態(tài),此時(shí)線(xiàn)程不可能執(zhí)行;</p><p>Runnable:當(dāng)調(diào)用thread.start()后,線(xiàn)程變成為Runnable狀態(tài)。只要得到CPU,就可以執(zhí)行;</p><p>Running:線(xiàn)程正在執(zhí)行;</p><p>Waiting:執(zhí)行thread.join()或在鎖對(duì)象調(diào)用obj.wait()等情況就會(huì)進(jìn)該狀態(tài),表明線(xiàn)程正處于等待某個(gè)資源或條件發(fā)生來(lái)喚醒自己;</p><p>Timed_Waiting:執(zhí)行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就會(huì)進(jìn)該狀態(tài),與Waiting的區(qū)別在于Timed_Waiting的等待有時(shí)間限制;</p><p>Blocked:如果進(jìn)入同步方法或同步代碼塊,沒(méi)有獲取到鎖,則會(huì)進(jìn)入該狀態(tài);</p><p>Dead:線(xiàn)程執(zhí)行完畢,或者拋出了未捕獲的異常之后,會(huì)進(jìn)入dead狀態(tài),表示該線(xiàn)程結(jié)束</p><h4>1.3 對(duì)于jstack日志,我們要著重關(guān)注如下關(guān)鍵信息</h4><p>Deadlock:表示有死鎖</p><p>Waiting on condition:等待某個(gè)資源或條件發(fā)生來(lái)喚醒自己。具體需要結(jié)合jstacktrace來(lái)分析,比如線(xiàn)程正在sleep,網(wǎng)絡(luò)讀寫(xiě)繁忙而等待</p><p>Blocked:阻塞</p><p>Waiting on monitor entry:在等待獲取鎖</p><p>in Object.wait():獲取鎖后又執(zhí)行obj.wait()放棄鎖</p><h4>1.4 Waiting on monitor entry 和 in Object.wait()的詳細(xì)描述</h4><p>Monitor是 Java中用以實(shí)現(xiàn)線(xiàn)程之間的互斥與協(xié)作的主要手段,它可以看成是對(duì)象或者 Class的鎖。每一個(gè)對(duì)象都有,也僅有一個(gè) monitor。從下圖中可以看出,每個(gè) Monitor在某個(gè)時(shí)刻,只能被一個(gè)線(xiàn)程擁有,該線(xiàn)程就是 "Active Thread",而其它線(xiàn)程都是 "Waiting Thread",分別在兩個(gè)隊(duì)列 " Entry Set"和 "Wait Set"里面等候。在 "Entry Set"中等待的線(xiàn)程狀態(tài)是 "Waiting for monitor entry",而在 "Wait Set"中等待的線(xiàn)程狀態(tài)是 "in Object.wait()"</p><h3>2 舉例說(shuō)明</h3><h4>2.1 blocked 的例子</h4><p><img src=    public static void main(String[] args) {           final Thread thread = new Thread() {               @Override               public void run() {                   synchronized (this) {                       System.out.println(Thread.currentThread().getName());                       try {                           wait();                       } catch (InterruptedException e) {                           // TODO Auto-generated catch block                           e.printStackTrace();                       }                   }               }           };           thread.start();           thread.setName("zouxh");//起名字,方便在線(xiàn)程棧里面進(jìn)行查看           try {               TimeUnit.SECONDS.sleep(3);           } catch (InterruptedException e) {               // TODO Auto-generated catch block               e.printStackTrace();           }           synchronized (thread) {               System.out.println(Thread.currentThread().getName());               try {                   TimeUnit.SECONDS.sleep(30);               } catch (InterruptedException e) {                   // TODO Auto-generated catch block                   e.printStackTrace();               }               thread.notify();           }       }

執(zhí)行后,查看jstack的日志如下:

"zouxh" prio=5 tid=7fe18c97b800 nid=0x115e58000 in Object.wait() [115e57000]

java.lang.Thread.State: WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

- waiting on <7f3112fe8> (a jstat.MainWati$1)

at java.lang.Object.wait(Object.java:485)

at jstat.MainWati$1.run(MainWati.java:16)

- locked <7f3112fe8> (a jstat.MainWati$1)

"main" prio=5 tid=7fe18c000800 nid=0x10c47b000

waiting on condition [10c47a000]

java.lang.Thread.State: TIMED_WAITING (sleeping)

at java.lang.Thread.sleep(Native Method)

at java.lang.Thread.sleep(Thread.java:300)

at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:328)

at jstat.MainWati.main(MainWati.java:37)

- locked <7f3112fe8> (a jstat.MainWati$1)

可以看到由于調(diào)用了object.wait()方法的時(shí)候放棄了鎖,所以zouxh這個(gè)線(xiàn)程就出現(xiàn)了object.wait()狀態(tài),線(xiàn)程的狀態(tài)就是waiting,等待notify來(lái)進(jìn)行喚醒。

由于mian線(xiàn)程在獲得zouxh的線(xiàn)程鎖后,調(diào)用了sleep方法,所以此時(shí)進(jìn)入了wating on condition等待某一個(gè)資源,進(jìn)入到time_waiting狀態(tài)。

2.3 waiting on conditon

    private static BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(1);
 
    public static void main(String[] args) {
 
        blockingQueue.add("zouxh");
 
        try {
 
            //阻塞的添加
 
            blockingQueue.put("ssss");
 
        } catch (InterruptedException e) {
 
            // TODO Auto-generated catch block
 
            e.printStackTrace();
 
        }
 
    }

線(xiàn)程棧如下:

"main" prio=5 tid=7f8f65000800 nid=0x10d7bb000 waiting on condition [10d7ba000]

java.lang.Thread.State: WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for <7f3110d80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)

at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:257)

at jstat.WatingTest.main(WatingTest.java:13)

此時(shí)main線(xiàn)程進(jìn)入了waiting on conditon狀態(tài),等待某一個(gè)資源,此時(shí)可以看到是在

a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObjec進(jìn)行了等待,阻塞住了,這是由于put發(fā)生了阻塞。

讀到這里,這篇“Java怎么通過(guò)jstack命令查詢(xún)?nèi)罩尽蔽恼乱呀?jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI