jstack命令以及線程轉(zhuǎn)儲(chǔ)堆棧分析

一蝠筑、命令介紹

jstack是jdk自帶的jvm分析工具肖卧,用于打印指定 java進(jìn)程core文件 或者遠(yuǎn)程 調(diào)試服務(wù) 的java線程棧信息沿盅,從而分析java程序性能不佳或者崩潰的問題。另外該命令是實(shí)驗(yàn)性的纫溃,不被支持嗡呼。

jstack命令非常簡單,使用自描述的幫助文檔皇耗,可以快速掌握其使用方法:

jstack -help
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

如上南窗,jstack命令作用的對(duì)象有三種,不同對(duì)象命令格式如下:

  1. 進(jìn)程: 使用jstack [-l] <pid>來連接到正在運(yùn)行的進(jìn)程郎楼,使用 jstack -F [-m] [-l] <pid>來連接到掛起的進(jìn)程万伤。
  2. core/executable: core文件是Linux下程序不正常退出產(chǎn)生的文件;executable文件是可產(chǎn)生core dump文件的java可執(zhí)行程序呜袁;使用jstack [-m] [-l] <executable> <core>命令敌买。
  3. 遠(yuǎn)程服務(wù): jstack [-m] [-l] [server_id@]<remote server IP or hostname>連接遠(yuǎn)程服務(wù)。

命令詳情參考: java 8關(guān)于jstack命令的介紹

snapshoot 快照

一個(gè)活躍的java程序阶界,其虛擬機(jī)內(nèi)的線程也是活躍的虹钮,不斷新建銷毀,在各個(gè)線程狀態(tài)之間轉(zhuǎn)移膘融。jstack命令芙粱,其實(shí)是對(duì)命令執(zhí)行時(shí)刻的虛擬機(jī)線程集合做一個(gè)快照,包含了當(dāng)前時(shí)刻虛擬機(jī)內(nèi)所有線程方法棧氧映。便于通過線程方法棧的行為春畔,定位程序性能不佳或者崩潰問題。這些行為主要是線程之間的同步岛都,如死鎖律姨,死循環(huán),等待外部資源競(jìng)爭鎖的行為臼疫。通過分析離線文件或者附著到正在運(yùn)行的java進(jìn)程择份,定位問題。

一窺方法棧

一段線程方法棧信息如下:

"localhost-startStop-1-SendThread(10.0.24.14:2181)" daemon prio=10 tid=0x00002b0ee8b4e000 nid=0x4b37 waiting for monitor entry [0x00002b0ed5162000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at org.apache.log4j.Category.callAppenders(Category.java:204)
    - waiting to lock <0x00000000db301138> (a org.apache.log4j.spi.RootLogger)
    at org.apache.log4j.Category.forcedLog(Category.java:391)
    at org.apache.log4j.Category.log(Category.java:856)
    at org.slf4j.impl.Log4jLoggerAdapter.info(Log4jLoggerAdapter.java:305)
    at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1156)

跟普通的java方法調(diào)用棧很相似烫堤,但是又多了些額外的信息荣赶,下面重點(diǎn)介紹這些額外的信息凤价。

二、線程狀態(tài)

jstack打印出的線程狀態(tài)與java線程狀態(tài)很相似讯壶,但并不是嚴(yán)格意義上相同。

java線程的狀態(tài)圖大概如下:

java線程狀態(tài)
  1. NEW: 實(shí)例化Thread類后的線程對(duì)象湾盗,不可執(zhí)行伏蚊。
  2. RUNNABLE: 調(diào)用線程的start()方法后;等待CPU時(shí)間片格粪。
  3. RUNNING: 獲得CPU時(shí)間片躏吊,正在執(zhí)行。
  4. WAITING: 線程等待其他線程執(zhí)行特定操作帐萎,等待時(shí)間不確定比伏。
  5. TIMED_WAITING: 線程等待其他線程執(zhí)行特定操作,等待時(shí)間確定疆导。
  6. BLOCKED: 進(jìn)入同步方法或者同步代碼塊赁项,沒有獲取到鎖,進(jìn)入該狀態(tài)澈段。
  7. TERMINATED: 線程執(zhí)行完畢悠菜,或者拋出未處理的異常,線程結(jié)束败富。

實(shí)際上悔醋,Thread的內(nèi)部枚舉類 java.lang.Thread.State 也對(duì)java線程狀態(tài)做了介紹,其中沒有 RUNNING 狀態(tài)兽叮,以上是考慮CPU調(diào)度引入的這個(gè)狀態(tài)芬骄。

thread states

jstack導(dǎo)出的線程方法棧狀態(tài)也是以java線程狀態(tài)為準(zhǔn),不過鹦聪,jvm中的實(shí)際線程狀態(tài)不包括NEW以及TERMINATED账阻,只包括:

  1. RUNNABLE
  2. WAITING
  3. TIMED_WAITING
  4. BLOCKED

Monitor機(jī)制

操作系統(tǒng)為支持進(jìn)程/線程間的同步,提供了一些基本的同步原語泽本,其中semaphore信號(hào)量 和 mutex互斥量是其中最重要的同步原語宰僧。但是使用基礎(chǔ)同步原語控制并發(fā)時(shí),程序員必須維護(hù)繁瑣的細(xì)節(jié)观挎,何時(shí)應(yīng)該加鎖琴儿,何時(shí)應(yīng)該喚醒進(jìn)程/線程;為便于開發(fā)并發(fā)程序嘁捷,一些高級(jí)語言支持了Monitor機(jī)制造成,類似語法糖,操作系統(tǒng)本身不支持Monitor雄嚣,其實(shí)現(xiàn)依賴基礎(chǔ)同步原語晒屎。

具體到高級(jí)語言Java喘蟆,synchronized ,Object(wait, notify/notifyAll)等元素提供了對(duì)Monitor機(jī)制的支持鼓鲁。直觀的代碼體現(xiàn)是 同步方法 或者 同步代碼塊(雖然java的鎖機(jī)制也提供線程同步蕴轨,但鎖機(jī)制與Monitor機(jī)制是不同的)。

下圖描述了線程狀態(tài)轉(zhuǎn)移與Monitor的關(guān)系:

thread&monitor

整個(gè)monitor分為三個(gè)區(qū)域骇吭,處于不同區(qū)域的線程有不同的狀態(tài):

  1. Entry Set(進(jìn)入?yún)^(qū)):線程欲獲取鎖橙弱,獲取鎖成功,進(jìn)入擁有者區(qū)域燥狰,否者在進(jìn)入?yún)^(qū)等待鎖棘脐;鎖釋放后,重新參與競(jìng)爭鎖龙致。
  2. The Owner(擁有者):線程成功獲得鎖蛀缝。
  3. Wait Set(等待區(qū)):由于必要條件不滿足,線程通過調(diào)用對(duì)象的wait方法目代,釋放鎖屈梁,并進(jìn)入等待區(qū)等待被notify/notifyAll喚醒。

Monitor機(jī)制中榛了,有且僅有一個(gè)線程可以成為Monitor的擁有者俘闯,這是這個(gè)線程是 An Active Thread;處于 Entry Set以及Wait Set的線程都是 Waiting Thread忽冻。

三真朗、線程轉(zhuǎn)儲(chǔ)堆棧分析

一條典型的jstack線程棧格式如下:

"線程名" [daemon] prio= os_prio= tid= nid= 線程動(dòng)作 [線程棧的起始地址]
    java.lang.Thread.State:線程狀態(tài) [(進(jìn)入該狀態(tài)的原因)]
     方法調(diào)用棧
     [-調(diào)用修飾]

    Locked ownable synchronizers:
        - <地址> (可持有同步器對(duì)象)

第一行說明線程相關(guān)信息,包括:

  1. 線程名僧诚。
  2. 是否守護(hù)線程遮婶,daemon標(biāo)識(shí),非守護(hù)線程沒有湖笨。
  3. 線程優(yōu)先級(jí)旗扑。
  4. 線程操作系統(tǒng)優(yōu)先級(jí)。
  5. 線程id慈省。
  6. 操作系統(tǒng)映射的線程id臀防,十六進(jìn)制字符串,使用這個(gè)id與實(shí)際操作系統(tǒng)線程id關(guān)聯(lián)边败。
  7. 線程動(dòng)作袱衷。
  8. 線程棧的起始地址。

線程動(dòng)作

需要特別說明的是笑窜,線程動(dòng)作致燥,它提供的額外信息利于定位問題;線程動(dòng)作包括:

  1. runnable: 線程可執(zhí)行排截,對(duì)應(yīng)的線程狀態(tài)一般為RUNNABLE, 也有例外對(duì)應(yīng)TIMED_WAITING嫌蚤。
  2. waiting on condition: 調(diào)用park阻塞辐益、等待區(qū)等待。
  3. waiting for monitor entry: 處于Monitor Entry Set脱吱,對(duì)應(yīng)的線程狀態(tài)一般是BLOCKED智政。
  4. in Object.wait(): 處于Monitor Wait Set,狀態(tài)為WAITING或TIMED_WAITING箱蝠。
  5. sleeping: 調(diào)用了sleep续捂,休眠。

第二行是線程的狀態(tài)抡锈,是java.lang.Thread.State中的一種疾忍;后面的括號(hào)里是進(jìn)入該狀態(tài)的原因(可選)乔外。

方法調(diào)用棧緊隨其后床三,重要的同步信息也會(huì)被輸出。

調(diào)用修飾

調(diào)用修飾是線程方法調(diào)用過程中杨幼,重要的同步信息撇簿;調(diào)用修飾包括:

  1. locked <地址> (目標(biāo)): 使用synchronized成功獲得對(duì)象鎖,即Monitor的擁有者差购。
  2. waiting to lock <地址> (目標(biāo)): 使用synchronized獲取對(duì)象鎖失敗四瘫,進(jìn)入Entry Set等待。
  3. waiting on <地址> (目標(biāo)): 使用synchronized獲取對(duì)象鎖成功后欲逃,必要條件不滿足找蜜,調(diào)用object.wait()進(jìn)入Wait Set等待。
  4. parking to wait for <地址> (目標(biāo)): 調(diào)用park稳析。

同步原語park比較特殊洗做,不屬于Monitor機(jī)制,他是鎖機(jī)制的基礎(chǔ)支持彰居。由Unsafe類的native方法park實(shí)現(xiàn)诚纸。

最后一行是指定了 -l 選項(xiàng)才會(huì)輸出的,額外的鎖信息陈惰。表示當(dāng)前線程獲得的可持有同步器畦徘。由此可見Monitor機(jī)制(synchronized系列)的得天獨(dú)厚,線程方法棧對(duì)Monitor機(jī)制的同步信息進(jìn)行了詳盡的說明抬闯。Monitor同步機(jī)制下井辆,Locked ownable synchronizers為None。由于鎖機(jī)制的Lock只是普通的java類溶握,jvm無從得知其詳盡的線程同步情況掘剪,因此使用鎖機(jī)制實(shí)現(xiàn)的線程同步,出現(xiàn)問題時(shí)奈虾,不如monitor機(jī)制的同步實(shí)現(xiàn)夺谁,不利于辨識(shí)廉赔。

三、線程動(dòng)作&調(diào)用修飾實(shí)踐

分析jstack的線程方法棧匾鸥,主要就是分析線程之間的同步信息蜡塌,以及其方法調(diào)用棧。以上詳細(xì)介紹了分析jstack的理論知識(shí)勿负,下面從實(shí)際代碼角度馏艾,分析jstack線程方法棧。

首先準(zhǔn)備好幾個(gè)同步方法奴愉,用于多線程環(huán)境下調(diào)用:

public class JStack {
    // 鎖機(jī)制
    static Lock lock = new ReentrantLock();
    // 鎖條件對(duì)象
    static Condition condition = lock.newCondition();

    static boolean first = true;

    /**
     * Monitor機(jī)制下的同步
     */
    static void monitorSync() {
        synchronized (JStack.class) {
            while (true) ;
        }
    }

    /**
     * Monitor機(jī)制下 條件等待
     *
     * @throws InterruptedException
     */
    static void monitorSyncWait() throws InterruptedException {
        synchronized (JStack.class) {
            if (first) {
                first = false;
                while (!first) {
                    JStack.class.wait();
                }
            }
            while (true) ;
        }
    }

    /**
     * lock機(jī)制下的同步
     */
    static void lockSync() {
        lock.lock();
        try {
            while (true) ;
        } finally {
            lock.unlock();
        }
    }

    /**
     * lock機(jī)制下條件等待
     *
     * @throws InterruptedException
     */
    static void lockSyncAwait() throws InterruptedException {
        lock.lock();
        try {
            if (first) {
                first = false;
                while (!first) {
                    condition.await();
                }
            }
            while (true) ;
        } finally {
            lock.unlock();
        }
    }
}

1) Monitor機(jī)制琅摩,synchronized競(jìng)爭鎖

多線程synchronized競(jìng)爭鎖:

public static void main(String[] args) {
    // Monitor機(jī)制,synchronized競(jìng)爭鎖
    Thread monitorSync1 = new Thread(JStack::monitorSync);
    monitorSync1.setName("SYNC monitor#1");
    Thread monitorSync2 = new Thread(JStack::monitorSync);
    monitorSync2.setName("SYNC monitor#2");

    monitorSync1.start();
    monitorSync2.start();
}
"SYNC monitor#2" #12 prio=5 os_prio=0 tid=0x000000001f299800 nid=0x3630 waiting for monitor entry [0x000000001fc7f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at jstack.JStack.monitorSync(JStack.java:27)
        - waiting to lock <0x000000076b87f128> (a java.lang.Class for jstack.JStack)
        at jstack.JStack$$Lambda$2/1989780873.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"SYNC monitor#1" #11 prio=5 os_prio=0 tid=0x000000001f299000 nid=0x1854 runnable [0x000000001fb7f000]
   java.lang.Thread.State: RUNNABLE
        at jstack.JStack.monitorSync(JStack.java:27)
        - locked <0x000000076b87f128> (a java.lang.Class for jstack.JStack)
        at jstack.JStack$$Lambda$1/2093631819.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

可見锭硼,Monitor機(jī)制下房资,使用synchronized競(jìng)爭鎖,

  • Monitor擁有者SYNC monitor#1的調(diào)用修飾是 lock檀头,線程動(dòng)作是runnable轰异,狀態(tài)是RUNNABLE
  • 競(jìng)爭鎖失敗的線程SYNC monitor#2的調(diào)用修飾是 waiting to lock,地址和目標(biāo)與擁有者線程相同暑始,線程動(dòng)作是waiting for monitor entry(在Entry Set等待)搭独,狀態(tài)是BLOCKED(在對(duì)象監(jiān)視器上阻塞)。

2) 鎖機(jī)制廊镜,競(jìng)爭鎖

多線程競(jìng)爭lock鎖:

public static void main(String[] args) {
    //  鎖機(jī)制牙肝,競(jìng)爭鎖
    Thread lockSync1 = new Thread(JStack::lockSync);
    lockSync1.setName("SYNC lock#1");
    Thread lockSync2 = new Thread(JStack::lockSync);
    lockSync2.setName("SYNC lock#2");

    lockSync1.start();
    lockSync2.start();
}
"SYNC lock#2" #12 prio=5 os_prio=0 tid=0x000000001f1e8800 nid=0x4d8 waiting on condition [0x000000001fbde000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076b8876d0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
        at jstack.JStack.lockSync(JStack.java:52)
        at jstack.JStack$$Lambda$2/1989780873.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"SYNC lock#1" #11 prio=5 os_prio=0 tid=0x000000001f1e8000 nid=0x172c runnable [0x000000001fadf000]
   java.lang.Thread.State: RUNNABLE
        at jstack.JStack.lockSync(JStack.java:54)
        at jstack.JStack$$Lambda$1/2093631819.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x000000076b8876d0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

可見,鎖機(jī)制下嗤朴,鎖競(jìng)爭同步原語都是park:

  • 鎖擁有鎖線程 SYNC lock#1獲取鎖并沒有調(diào)用修飾配椭,而在Locked ownable synchronizers 指明其擁有的可持有同步器(鎖),線程動(dòng)作是runnable播赁,狀態(tài)時(shí)RUNNABLE颂郎。
  • 競(jìng)爭鎖失敗線程SYNC lock#2的調(diào)用修飾是parking to wait for,地址和對(duì)象正是擁有者線程持有的鎖容为,線程動(dòng)作是waiting on condition乓序,狀態(tài)是WAITING(parking),不同于Monitor未獲得鎖處于BLOCKED狀態(tài)坎背。

3) Monitor機(jī)制替劈,條件對(duì)象上等待

多線程環(huán)境下,在monitor機(jī)制的條件對(duì)象上等待:

public static void main(String[] args) {
    // Monitor機(jī)制得滤,條件對(duì)象上等待
    Thread monitorSyncCon1 = new Thread(() -> {
        try {
            monitorSyncWait();
        } catch (InterruptedException e) {
            // suppressed
        }
    });
    monitorSyncCon1.setName("SYNC monitor condition#1");
    Thread monitorSyncCon2 = new Thread(() -> {
        try {
            monitorSyncWait();
        } catch (InterruptedException e) {
            // suppressed
        }
    });
    monitorSyncCon2.setName("SYNC monitor condition#2");
    monitorSyncCon1.start();
    monitorSyncCon2.start();
}
"SYNC monitor condition#2" #12 prio=5 os_prio=0 tid=0x000000001ed0b000 nid=0x31f8 runnable [0x000000001f6ff000]
   java.lang.Thread.State: RUNNABLE
        at jstack.JStack.monitorSyncWait(JStack.java:44)
        - locked <0x000000076b87f348> (a java.lang.Class for jstack.JStack)
        at jstack.JStack.lambda$main$1(JStack.java:110)
        at jstack.JStack$$Lambda$2/1989780873.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"SYNC monitor condition#1" #11 prio=5 os_prio=0 tid=0x000000001ed0a000 nid=0x30d0 in Object.wait() [0x000000001f5fe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076b87f348> (a java.lang.Class for jstack.JStack)
        at java.lang.Object.wait(Object.java:502)
        at jstack.JStack.monitorSyncWait(JStack.java:41)
        - locked <0x000000076b87f348> (a java.lang.Class for jstack.JStack)
        at jstack.JStack.lambda$main$0(JStack.java:102)
        at jstack.JStack$$Lambda$1/2093631819.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

可見陨献,Monitor機(jī)制下,在條件對(duì)象上等待:

  • 在條件對(duì)象上等待的線程SYNC monitor condition#1, 首先 locked <0x000000076b87f348>獲得鎖成為擁有者懂更,接著主動(dòng)調(diào)用wait方法眨业,waiting on <0x000000076b87f348>后釋放鎖急膀,在條件對(duì)象上等待,進(jìn)入Wait Set龄捡,線程動(dòng)作是in Object.wait()卓嫂,狀態(tài)是WAITING(在對(duì)象監(jiān)視器上等待)。
  • 此時(shí)成為擁有者的線程SYNC monitor condition#2聘殖,在線程SYNC monitor condition#1主動(dòng)放棄鎖后 locked <0x000000076b87f348>獲得同一個(gè)鎖晨雳,線程動(dòng)作是runnable,線程狀態(tài)是RUNNABLE奸腺。

4) Lock機(jī)制餐禁,條件對(duì)象上等待

多線程環(huán)境下,競(jìng)爭lock對(duì)象的條件對(duì)象:

public static void main(String[] args) {
    // Lock機(jī)制突照,條件對(duì)象上等待
    Thread lockSyncCon1 = new Thread(() -> {
        try {
            lockSyncAwait();
        } catch (InterruptedException e) {
            // suppressed
        }
    });
    lockSyncCon1.setName("SYNC lock condition#1");
    Thread lockSyncCon2 = new Thread(() -> {
        try {
            lockSyncAwait();
        } catch (InterruptedException e) {
            // suppressed
        }
    });
    lockSyncCon2.setName("SYNC monitor condition#2");
    lockSyncCon1.start();
    lockSyncCon2.start();
}

"SYNC monitor condition#2" #12 prio=5 os_prio=0 tid=0x000000001f1aa800 nid=0x135c waiting on condition [0x000000001fb9e000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076b8894f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at jstack.JStack.lockSyncAwait(JStack.java:71)
        at jstack.JStack.lambda$main$1(JStack.java:131)
        at jstack.JStack$$Lambda$2/1989780873.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"SYNC lock condition#1" #11 prio=5 os_prio=0 tid=0x000000001f1aa000 nid=0x330c runnable [0x000000001fa9f000]
   java.lang.Thread.State: RUNNABLE
        at jstack.JStack.lockSyncAwait(JStack.java:74)
        at jstack.JStack.lambda$main$0(JStack.java:123)
        at jstack.JStack$$Lambda$1/2093631819.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - <0x000000076b887af0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

可見帮非,在lock條件對(duì)象上等待:

  • 一開始獲得鎖的線程SYNC monitor condition#2,后來放棄鎖在鎖的條件對(duì)象上等待绷旗,方法調(diào)用棧中并沒有提現(xiàn)這一個(gè)過程喜鼓,只是在最后說明副砍,該線程parking to wait for <0x000000076b8894f8>衔肢,線程動(dòng)作是 waiting on condition,狀態(tài)是WAITING (parking)
  • 由于線程SYNC monitor condition#2主動(dòng)釋放鎖而獲得鎖的線程SYNC lock condition#1豁翎,Locked ownable synchronizers指示它獲得一個(gè)鎖角骤,處于RUNNABLE狀態(tài)。

以上心剥,wait或者await方法加上一個(gè)超時(shí)時(shí)間邦尊,WAITING狀態(tài)變?yōu)門IMED_WAITING狀態(tài)

4) sleep

try {
    Thread.sleep(50_000);
} catch (InterruptedException e) {
    // suppressed
}
"main" #1 prio=5 os_prio=0 tid=0x00000000036e2800 nid=0x2aa8 waiting on condition [0x00000000035df000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at jstack.JStack.main(JStack.java:141)

   Locked ownable synchronizers:
        - None

REFER TO

[1] linux:core文件的產(chǎn)生和調(diào)試
[2] Java 中的 Monitor 機(jī)制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市优烧,隨后出現(xiàn)的幾起案子蝉揍,更是在濱河造成了極大的恐慌,老刑警劉巖畦娄,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件又沾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡熙卡,警方通過查閱死者的電腦和手機(jī)杖刷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驳癌,“玉大人滑燃,你說我怎么就攤上這事⊥窍剩” “怎么了表窘?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵典予,是天一觀的道長。 經(jīng)常有香客問我乐严,道長熙参,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任麦备,我火速辦了婚禮孽椰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凛篙。我一直安慰自己黍匾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布呛梆。 她就那樣靜靜地躺著锐涯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪填物。 梳的紋絲不亂的頭發(fā)上纹腌,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音滞磺,去河邊找鬼升薯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛击困,可吹牛的內(nèi)容都是我干的涎劈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼阅茶,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蛛枚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脸哀,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤蹦浦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后撞蜂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盲镶,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年谅摄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徒河。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡送漠,死狀恐怖顽照,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤代兵,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布尼酿,位于F島的核電站,受9級(jí)特大地震影響植影,放射性物質(zhì)發(fā)生泄漏裳擎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一思币、第九天 我趴在偏房一處隱蔽的房頂上張望鹿响。 院中可真熱鬧,春花似錦谷饿、人聲如沸惶我。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绸贡。三九已至,卻和暖如春毅哗,著一層夾襖步出監(jiān)牢的瞬間听怕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工虑绵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿瞭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓蒸殿,卻偏偏與公主長得像筷厘,于是被迫代替她去往敵國和親鸣峭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宏所,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 一、top(Linux命令) 執(zhí)行top命令: (查看進(jìn)程15477的詳細(xì)情況摊溶,下文用到) 系統(tǒng)信息(前五行): ...
    java菜閱讀 1,150評(píng)論 0 1
  • jstack用于打印出給定的java進(jìn)程ID或core file或遠(yuǎn)程調(diào)試服務(wù)的Java堆棧信息爬骤,如果是在64位機(jī)...
    sherlock_6981閱讀 950評(píng)論 0 0
  • jstack jstack是java虛擬機(jī)自帶的一種堆棧跟蹤工具。 功能 jstack用于生成java虛擬機(jī)當(dāng)前時(shí)...
    Kate_Blog閱讀 1,225評(píng)論 0 3
  • 我有三個(gè)舅舅莫换,一個(gè)阿姨霞玄。三舅自我出生后,看了我一眼后拉岁,第二年就說去江蘇打拼坷剧,在那個(gè)連通訊都難以聯(lián)絡(luò)的時(shí)代,三舅自從...
    黃秋明閱讀 270評(píng)論 0 0
  • 抱怨喊暖,總是能聽到各種抱怨惫企,所謂一升米養(yǎng)恩人,一斗米養(yǎng)仇人。 抱怨唯一的好處就是于周圍人處于一種看似融洽狞尔,卻各有打算...
    律人閱讀 285評(píng)論 0 0