java線程狀態(tài)與jstack

背景


在實(shí)際的項(xiàng)目中,我們?cè)诰帉懸恍└卟l(fā)的項(xiàng)目的時(shí)候滩援,經(jīng)常會(huì)自己的來控制線程栅隐,但是又很容易出現(xiàn)問題,一旦出現(xiàn)問題又很難debug調(diào)試玩徊。筆者在實(shí)際中會(huì)經(jīng)常起多線程來并發(fā)的執(zhí)行任務(wù)租悄,總結(jié)了一些排查多線程的問題的方法。

工具使用

如何借助一些工具來排查線程上的bug?

  1. jps: 可以查看當(dāng)先系統(tǒng)運(yùn)行了哪些java進(jìn)程恩袱,同時(shí)會(huì)打印進(jìn)程號(hào)泣棋。
C:\Users\robin>jps
8976 DeadLock
10588
4700 Launcher
6492 Jps
  1. jstack: 可以根據(jù)進(jìn)程號(hào)來查看該進(jìn)程里線程的詳細(xì)狀態(tài)。
jstack 8976 > d:/DeadLock.txt
  1. top: linux下查看系統(tǒng)資源的指令畔塔,我們可以看自己java進(jìn)程的cpu和內(nèi)存占用情況潭辈。

線程的狀態(tài)

java 線程的狀態(tài):
NEW、RUNNABLE澈吨、BLOCKED把敢、WAITING、TIMED_WAITING谅辣、TERMINATED還有RUNNING修赞、DEADLOCK

先來看下jdk的源碼,看下官方對(duì)線程的幾種狀態(tài)的闡述:

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

從以上的注釋中我們可以發(fā)現(xiàn):

  1. NEW: 是線程這個(gè)對(duì)象剛被new出來桑阶,還不能被執(zhí)行柏副。

  2. RUNNABLE: 這個(gè)狀態(tài)是線程已經(jīng)被new出來了,并且調(diào)用了start()方法蚣录,此線程隨時(shí)被執(zhí)行割择,只要分配到cpu時(shí)間片就能進(jìn)入執(zhí)行狀態(tài)。

  3. BLOCKED: 這個(gè)狀態(tài)是執(zhí)行的線程遇到遇到同步方法(synchronized)或者同步代碼塊而沒有得到鎖萎河,將進(jìn)入阻塞狀態(tài)荔泳。

  4. WAITING: 當(dāng)執(zhí)行的線程調(diào)用了join() 或者 wait() 方法的時(shí)候蕉饼,就會(huì)進(jìn)入等待狀態(tài),直到被喚醒换可。

  5. TIMED_WAITING: 這個(gè)狀態(tài)就是當(dāng)用了sleep(1000)或者join(1000)或者wait(1000)時(shí)椎椰,執(zhí)行的線程就會(huì)進(jìn)入等待狀態(tài)厦幅,與WAITING不同的是沾鳄,這個(gè)狀態(tài)的等待是有時(shí)間限制的。

  6. TERMINATED: 這個(gè)狀態(tài)表示線程已經(jīng)執(zhí)行完成了确憨。

  7. RUNNING: 執(zhí)行的中的線程的狀態(tài)译荞,官網(wǎng)認(rèn)為正常執(zhí)行中的線程是屬于正常的,也就沒有打印出運(yùn)行中的狀態(tài)休弃。如果你想看運(yùn)行中的線程信息吞歼,那么可以取看自己項(xiàng)目的日志信息或者控制臺(tái)。

  8. DEADLOCK: 對(duì)于這種狀態(tài)塔猾,是死鎖狀態(tài)篙骡,一旦出現(xiàn)這種情況的話,需要立即更改丈甸,否則會(huì)造成意想不到的后果糯俗。

對(duì)于死鎖狀態(tài)比較重要,我們一定要會(huì)識(shí)別睦擂,下面筆者寫了一個(gè)死鎖得湘,然后使用jstack打印出的日志:

"VM Periodic Task Thread" os_prio=2 tid=0x000000001993f000 nid=0x1c88 waiting on condition 

JNI global references: 22


Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00000000038cae58 (object 0x00000000d609a170, a java.util.ArrayList),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00000000038c99b8 (object 0x00000000d609a188, a java.util.ArrayList),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at DeadLock.run(DeadLock.java:37)
    - waiting to lock <0x00000000d609a170> (a java.util.ArrayList)
    - locked <0x00000000d609a188> (a java.util.ArrayList)
    at java.lang.Thread.run(Thread.java:748)
"Thread-0":
    at DeadLock.run(DeadLock.java:37)
    - waiting to lock <0x00000000d609a188> (a java.util.ArrayList)
    - locked <0x00000000d609a170> (a java.util.ArrayList)
    at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

可以看出,jstack的日志信息給出非常明顯的提示Found one Java-level deadlock: 提示發(fā)現(xiàn)一個(gè)死鎖顿仇,可以根據(jù)下面的信息淘正,就能定位在哪個(gè)類,哪一行發(fā)生了死鎖臼闻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸿吆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子述呐,更是在濱河造成了極大的恐慌惩淳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件市埋,死亡現(xiàn)場(chǎng)離奇詭異黎泣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)缤谎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門抒倚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坷澡,你說我怎么就攤上這事托呕。” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵项郊,是天一觀的道長(zhǎng)馅扣。 經(jīng)常有香客問我,道長(zhǎng)着降,這世上最難降的妖魔是什么差油? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮任洞,結(jié)果婚禮上蓄喇,老公的妹妹穿的比我還像新娘。我一直安慰自己交掏,他們只是感情好妆偏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盅弛,像睡著了一般钱骂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挪鹏,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天见秽,我揣著相機(jī)與錄音,去河邊找鬼狰住。 笑死张吉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的催植。 我是一名探鬼主播肮蛹,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼创南!你這毒婦竟也來了伦忠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤稿辙,失蹤者是張志新(化名)和其女友劉穎昆码,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邻储,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赋咽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吨娜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓匿。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宦赠,靈堂內(nèi)的尸體忽然破棺而出陪毡,到底是詐尸還是另有隱情米母,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布毡琉,位于F島的核電站铁瞒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桅滋。R本人自食惡果不足惜慧耍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虱歪。 院中可真熱鬧蜂绎,春花似錦、人聲如沸笋鄙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萧落。三九已至,卻和暖如春洗贰,著一層夾襖步出監(jiān)牢的瞬間找岖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工敛滋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留许布,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓绎晃,卻偏偏與公主長(zhǎng)得像蜜唾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庶艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

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

  • 一袁余、top(Linux命令) 執(zhí)行top命令: (查看進(jìn)程15477的詳細(xì)情況,下文用到) 系統(tǒng)信息(前五行): ...
    java菜閱讀 1,141評(píng)論 0 1
  • jstack jstack是java虛擬機(jī)自帶的一種堆棧跟蹤工具咱揍。 功能 jstack用于生成java虛擬機(jī)當(dāng)前時(shí)...
    Kate_Blog閱讀 1,218評(píng)論 0 3
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,089評(píng)論 0 23
  • jstack用于打印出給定的java進(jìn)程ID或core file或遠(yuǎn)程調(diào)試服務(wù)的Java堆棧信息颖榜,如果是在64位機(jī)...
    sherlock_6981閱讀 928評(píng)論 0 0
  • 數(shù)學(xué)老師今天沒給我們講新課,數(shù)學(xué)老師就教給了我們口算怎么算煤裙,第一個(gè)是接著往上數(shù)或者分成掩完,然后老師來出題讓同學(xué)們來看...
    張若涵閱讀 90評(píng)論 0 0