[翻訳]Javaスレッドdumpsの分析方法

20963 ワード

これは故障診断に関する文章の第2編で、「How to Analyze Java Thread Dumps」から翻訳され、原文の住所:https://dzone.com/articles/how-analyze-java-thread-dumps
——————————————不思議な分割線————————————
この文章の内容は最初にTae Jin GuがCubrid blogに発表した.カートンが存在する場合、またはチャンスJavaのwebアプリケーションが予想より遅い場合、thread dumpsを使用する必要があります.thread dumpsがあなたにとって非常に複雑だと思ったら、本文はあなたの理解を助けます.Javaのスレッドthreadsとは何か、どのようなタイプがあるのか、どのように作成されたのか、どのように管理されているのか、どのように実行にdump threadsを適用するのか、最後にdumpファイルを分析し、ボトルネックを見つけたり、スレッドをブロックしたりするのかを説明します.この文章はjava応用debugの経験を豊富にした結晶である.
JAvaとスレッド(Thread)
Webサーバは、数十~数百のスレッドを使用して、大量の同時ユーザ要求を処理します.2つ以上のスレッドが同じリソースを使用する必要がある場合、スレッド間で競合が発生し、デッドロックが発生することもあります.
スレッド競合とは、スレッドがロックを待機している状態であり、このロックが他のスレッドロックによって保持されていることを意味する.Webアプリケーションでは、異なるスレッドが共有リソースに頻繁にアクセスします.たとえば、ログを記録するには、ログを記録する必要があるニュータウンが関連するロックを取得し、共有リソースにアクセスする必要があります.
デッドロックは特殊なタイプのスレッド競合であり、この場合、2つ以上のスレッドは他のスレッドが作業を完了してから自分のタスクを完了するのを待つことができます.
Javaスレッドの背景知識
スレッド同期
スレッドは、他のスレッドと同時に調整できます.複数のスレッドが共有リソースにアクセスする必要がある場合は、正確性を保証するために、スレッド同期保証を使用し、共有リソースにアクセスできるスレッドが1つしかないことを保証する必要があります.
JAvaでのスレッド同期はモニタ(monitor)を使用して実現できます.Javaオブジェクトごとに一意のモニタがあります.モニタは1つのスレッドのみで占有できます.1つのスレッドが別のスレッドで取得したモニタオブジェクトを占有する場合は、モニタの待機キューで他のスレッドがモニタを解放するのを待つ必要があります.
スレッドのステータス
スレッドdumpを解析するには,スレッドの様々な状態を理解する必要がある.これらのステータスはjavaです.lang.Thread.Stateにリストされています.
  • NEW:スレッドが作成されたばかりでまだ実行されていません.
  • RUNNABLE:スレッドはcpuリソースを占有し、タスク(オペレーティングシステムのリソーススケジューリングのためWATING状態にある可能性がある)を処理している
  • .
  • BLOCKED:モニタロックを取得するために、スレッドは他のスレッド解放ロック
  • を待っている.
  • WAITING:スレッドはwait,joinまたはpardメソッドを使用して
  • を待つ
  • TIMED_WAITING:スレッドはsleep,wait,joinまたはparkメソッドを使用して待機する.(WAITING状態とは異なる方法パラメータは最大待ち時間を指定しており、WAITING状態は時間的にも外部的にも変更可能である)
  • .
    スレッドタイプ
    JAvaスレッドは、次の2つに分類できます.
  • daemonスレッド(スプライトスレッド、バックグラウンドスレッドとも考えられる)
  • 非daemonスレッド他の非daemonスレッドが存在しない場合、deamonスレッドは動作を停止します.スレッドを作成しなくてもjavaアプリケーションではデフォルトで複数のスレッドが作成されます.彼らの多くはdaemonスレッドで、主にgcやJMXなどに使われています.

  • static void main(String[]args)を実行する方法は、daemon以外のスレッドとして作成され、このスレッドが停止すると、他のdaemonスレッドもすべて停止します.
    thread dumpの作成
    最もよく使われる3つの方法を紹介します.他にもdumpデータを得る方法がたくさんあることに注意してください.1回のthread dumpではdump時刻のスレッド状態しか表示できないので、スレッド状態の変化を見るためには、5秒ごとにdumpを1回、合計dump 5-10回が推奨されます.
    jstackによるthread dump
    jdk 1で.6および高バージョンでは、windowsシステムでjstackを使用してthread dumpを行うことができます.
    jps -v jstack -f 5824
    jspを用いてjavaプロセスのpidを取得し、pidをjstackのパラメータとしてthread dumpを取得する
    jVisualVMによるthread dumpの取得
    jVisualVMのようなソフトウェアを使用してthread dumpファイルを生成します.
    linux端末で生成
    ps-efコマンドですべてのプロセスPidをリストし、対応するjavaプロセスpidを見つけます.
    ps -ef | grep java
    対応するPidをkill-3のパラメータとしてthread dumpを取得する.
    スレッドdumpファイルのスレッド情報
    "pool-1-thread-13" prio=6 tid=0x000000000729a000 nid=0x2fb4 runnable [0x0000000007f0f000] java.lang.Thread.State: RUNNABLE
                  at java.net.SocketInputStream.socketRead0(Native Method)
                  at java.net.SocketInputStream.read(SocketInputStream.java:129)
                  at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
                  at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
                  at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
                  - locked <0x0000000780b7e688> (a java.io.InputStreamReader)
                  at java.io.InputStreamReader.read(InputStreamReader.java:167)
                  at java.io.BufferedReader.fill(BufferedReader.java:136)
                  at java.io.BufferedReader.readLine(BufferedReader.java:299)
                  - locked <0x0000000780b7e688> (a java.io.InputStreamReader)
                  at java.io.BufferedReader.readLine(BufferedReader.java:362)
    
  • スレッド名:javaを使用する場合.lang.Threadクラスがスレッドを生成する場合、javaを使用する場合、スレッドはThread-(NUmber(シーケンス番号))と命名される.util.concurrent.ThreadFacotryクラスの場合、pool-(number)-thread-(number)と命名する.
  • 優先度:便スレッド付き優先度
  • スレッドID:スレッドを表す一意のID(スレッドcpu使用率、メモリ使用率、スレッドidで取得可能ないくつかの重要な情報を含む)
  • .
  • スレッドステータス:スレッドを表すステータス
  • スレッド呼び出しスタック:スレッドを表す呼び出しスタック情報
  • タイプ別スレッドDump情報
    ロックを取得できない(BLOCKED)
    1つのスレッドがロックを取得して他のスレッドが取得できない場合、通常、アプリケーションのパフォーマンス全体が遅くなります.以下の例では、BLOCKED_TEST pool-1-thread-1は<0 x 00000780 a 000 b 0>ロックを占有し、BLOCKED_TEST pool-1-thread-2とBLOCKED_TEST pool-1-thread-3スレッドは、<0 x 000000780 a 000 b 0>ロックの取得を待っています.
    "BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]
       java.lang.Thread.State: RUNNABLE
                    at java.io.FileOutputStream.writeBytes(Native Method)
                    at java.io.FileOutputStream.write(FileOutputStream.java:282)
                    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
                    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
                    - locked <0x0000000780a31778> (a java.io.BufferedOutputStream)
                    at java.io.PrintStream.write(PrintStream.java:432)
                    - locked <0x0000000780a04118> (a java.io.PrintStream)
                    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
                    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
                    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
                    - locked <0x0000000780a040c0> (a java.io.OutputStreamWriter)
                    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
                    at java.io.PrintStream.newLine(PrintStream.java:496)
                    - locked <0x0000000780a04118> (a java.io.PrintStream)
                    at java.io.PrintStream.println(PrintStream.java:687)
                    - locked <0x0000000780a04118> (a java.io.PrintStream)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44)
                    - locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                    at java.lang.Thread.run(Thread.java:662)
       Locked ownable synchronizers:
                    - <0x0000000780a31758> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    "BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000]
       java.lang.Thread.State: BLOCKED (on object monitor)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43)
                    - waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                    at java.lang.Thread.run(Thread.java:662)
       Locked ownable synchronizers:
                    - <0x0000000780b0c6a0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    "BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000]
       java.lang.Thread.State: BLOCKED (on object monitor)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:42)
                    - waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                    at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                    at java.lang.Thread.run(Thread.java:662)
       Locked ownable synchronizers:
                    - <0x0000000780b0e1b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    

    デッドロック状態の場合
    この場合、スレッドaはスレッドbのロックを取得して動作を継続する必要があり、スレッドbはスレッドaのロックを必要として動作を継続する.スレッドdumpでは、DEADLOCK_が表示されます.TEST-1 threadは0 x 0000007 d 58 f 5 e 48ロックを持ち、0 x 0000007 d 58 f 5 e 60ロックを取得してみます.DEADLOCK_も見えますTEST-2 threadは0 x 0000007 d 58 f 5 e 60ロックを持ち、0 x 0000007 d 58 f 5 e 48ロックを取得しようとしている.各スレッドは、1つのスレッドがロックを放棄するまで、別のスレッドが持つロックの取得を待っていることがわかります.
    "DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                    - waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                    - locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
       Locked ownable synchronizers:
                    - None
    "DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                    - waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                    - locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
       Locked ownable synchronizers:
                    - None
    "DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                    - waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                    - locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                    at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
       Locked ownable synchronizers:
                    - None
    

    リモートサーバからメッセージを受信するのを待ち続けると
    この場合、スレッド状態がRUNNABLEとして表示されているため、スレッドは正常に見えます.ただし、thread dumpを時間ソートすると、socketReadThreadスレッドがsocketから情報を取得するのを待っていることがわかります.
    "socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]
       java.lang.Thread.State: RUNNABLE
                    at java.net.SocketInputStream.socketRead0(Native Method)
                    at java.net.SocketInputStream.read(SocketInputStream.java:129)
                    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
                    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
                    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
                    - locked <0x00000007d78a2230> (a java.io.InputStreamReader)
                    at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)
                    - locked <0x00000007d78a2230> (a java.io.InputStreamReader)
                    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)
                    at java.io.InputStreamReader.read(InputStreamReader.java:151)
                    at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)
                    at java.lang.Thread.run(Thread.java:662)
    

    待ち時間
    スレッドは待機(WAIT)状態のままです.スレッドdumpでは、IoWaitThreadスレッドがLinkedBlockingQueueからメッセージを受信するのを待つ.LinkedBlockingQueueにメッセージが入っていない場合、スレッドは待機状態のままになります.
    "IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]
       java.lang.Thread.State: WAITING (parking)
                    at sun.misc.Unsafe.park(Native Method)
                    - parking to wait for  <0x00000007d5c45850> (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.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)
                    at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)
                    at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)
                    at java.lang.Thread.run(Thread.java:662)
    

    スレッドリソースを効率的に整理していない場合
    スレッドリソースが組織を合理的に使用されていない場合、不要なスレッドが蓄積されます.このような場合、推奨される方法は、スレッドを監視したり、スレッドの終了条件をチェックしたりすることです.
    スレッドdumpを使用して問題を解決する場合
    ケース1:cpu使用率が異常に高い場合
    1、最高のcpu使用率を持つスレッドを見つける
    ps -mo pid.lwp.stime.time.cpu-C java(検証対象)
    アプリケーションからcpuの使用率が最も高いスレッドを見つけます.Cpuが最も多く使用されているLWP(スレッド)を見つけ、uid(10039)を16進数(0 x 2737)に変換します.
    2、thread dumpを取得した後、対応するスレッドを確認し、pidが10029のプロセスに対してthread dumpを行い、nidが0 x 2737のスレッドを探し出す
    "NioProcessor-2" prio=10 tid=0x0a8d2800 nid=0x2737 runnable [0x49aa5000]
    java.lang.Thread.State: RUNNABLE
                    at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
                    at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
                    at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
                    at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
                    - locked <0x74c52678> (a sun.nio.ch.Util$1)
                    - locked <0x74c52668> (a java.util.Collections$UnmodifiableSet)
                    - locked <0x74c501b0> (a sun.nio.ch.EPollSelectorImpl)
                    at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
                    at external.org.apache.mina.transport.socket.nio.NioProcessor.select(NioProcessor.java:65)
                    at external.org.apache.mina.common.AbstractPollingIoProcessor$Worker.run(AbstractPollingIoProcessor.java:708)
                    at external.org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                    at java.lang.Thread.run(Thread.java:662)
    

    各時間に複数回thread dumpを行い、対応するスレッドのスレッド状態を表示し、問題を特定します.
    ケース2:処理が遅くなると
    マルチスレッドdumpsを借りた後、BLOCKED状態のスレッドを見つけます.
    " DB-Processor-13" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f000]
    java.lang.Thread.State: BLOCKED (on object monitor)
                    at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
                    - waiting to lock <0xe0375410> (a beans.ConnectionPool)
                    at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
                    at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
    "DB-Processor-14" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f020]
    java.lang.Thread.State: BLOCKED (on object monitor)
                    at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
                    - waiting to lock <0xe0375410> (a beans.ConnectionPool)
                    at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
                    at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
    " DB-Processor-3" daemon prio=5 tid=0x00928248 nid=0x8b waiting for monitor entry [0x000000000825d080]
    java.lang.Thread.State: RUNNABLE
                    at oracle.jdbc.driver.OracleConnection.isClosed(OracleConnection.java:570)
                    - waiting to lock <0xe03ba2e0> (a oracle.jdbc.driver.OracleConnection)
                    at beans.ConnectionPool.getConnection(ConnectionPool.java:112)
                    - locked <0xe0386580> (a java.util.Vector)
                    - locked <0xe0375410> (a beans.ConnectionPool)
                    at beans.cus.Cue_1700c.GetNationList(Cue_1700c.java:66)
                    at org.apache.jsp.cue_1700c_jsp._jspService(cue_1700c_jsp.java:120)
    

    スレッドがblocked状態の場合、スレッドが取得したいロックに関連するスレッドを見つけます.thread dumpにより、スレッドがblocked状態にあることが確認されるのは、主にスレッドが0 xe 0375410ロックを取得できないためである.以上の問題は,対応するロックを占有するスレッドスタック情報を解析することによって解決できる.
    このような状況がデータベース管理システムを用いたアプリケーションで頻繁に発生する理由には,2つの理由がある.1つ目の理由は、不合理な構成によるものです.実際にスレッドが実行されていても、不合理なDBPP構成のため、最適なパフォーマンスが得られません.複数のthread dumpを比較すると、以前BLOCKED状態にあったスレッドが異なる状態にあることがわかります.
    2つ目の原因は、正常な接続ではありません.データベースへの接続が正常でない場合、スレッドはタイムアウトまで待機します.この場合、dumpを複数回比較しても、データベースに関連するスレッドはBLOCKED状態のままであることがわかります.タイムアウト時間などの構成を適切に変更することで、このような問題が持続する時間が少なくなります.
    Thread Dumpフレンドリーなコーディング実践
    スレッド名
    Javaを使用する場合.lang.Threadクラスがスレッドを生成する場合、javaを使用する場合、スレッドはThread-(NUmber(シーケンス番号))と命名される.util.concurrent.ThreadFacotryクラスの場合、pool-(number)-thread-(number)と命名する.分析アプリケーションに何百ものスレッドがある場合、すべてのスレッドがデフォルトの名前を使用すると、分析するスレッドを分解するのが難しいため、分析が非常に困難になります.
    したがって、スレッドを作成するのが偶数である場合、名前を指定する番号習慣を身につけることをお勧めします.
    Javaを使用する場合.lang.Threadスレッドを作成する場合、構築方法でスレッドに名前を付けることができます.
    public Thread(Runnable target, String name);
    public Thread(ThreadGroup group, String name);
    public Thread(ThreadGroup group, Runnable target, String name);
    public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
    

    Javaを使うとutil.concurrent.ThreadFactoryスレッドを作成する場合は、カスタムThreadFactoryを作成して名前を付けることができます.特別な機能が必要でない場合は、以下に説明するMyThreadFactoryを使用します.
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.atomic.AtomicInteger;
    public class MyThreadFactory implements ThreadFactory {
      private static final ConcurrentHashMap POOL_NUMBER =
                                                           new ConcurrentHashMap();
      private final ThreadGroup group;
      private final AtomicInteger threadNumber = new AtomicInteger(1);
      private final String namePrefix;
      public MyThreadFactory(String threadPoolName) {
          if (threadPoolName == null) {
              throw new NullPointerException("threadPoolName");
          }
                POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());
          SecurityManager securityManager = System.getSecurityManager();
          group = (securityManager != null) ? securityManager.getThreadGroup() :
                                                        Thread.currentThread().getThreadGroup();
          AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);
          if (poolCount == null) {
                namePrefix = threadPoolName + " pool-00-thread-";
          } else {
                namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";
          }
      }
      public Thread newThread(Runnable runnable) {
          Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);
          if (thread.isDaemon()) {
                thread.setDaemon(false);
          }
          if (thread.getPriority() != Thread.NORM_PRIORITY) {
                thread.setPriority(Thread.NORM_PRIORITY);
          }
          return thread;
      }
    }
    

    MBeanを使用して詳細を入手できます
    MBeanを使用してThreadInfo情報を取得できます.ThreadInfoでは、thread dumpでは入手しにくい情報をより多く入手できます.
    ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
    long[] threadIds = mxBean.getAllThreadIds();
    ThreadInfo[] threadInfos =
                    mxBean.getThreadInfo(threadIds);
    for (ThreadInfo threadInfo : threadInfos) {
      System.out.println(
          threadInfo.getThreadName());
      System.out.println(
          threadInfo.getBlockedCount());
      System.out.println(
          threadInfo.getBlockedTime());
      System.out.println(
          threadInfo.getWaitedCount());
      System.out.println(
          threadInfo.getWaitedTime());
    }
    

    まとめ
    本文が広範なコード友に助けを提供することを望みます
    More
    Thread Dumpの分析方法については多くの記事があり、dumpファイルを得た後、MAT、TDA、JProfilerなど多くのツールで使用できます.http://www.cnblogs.com/zhengyun_ustc/archive/2013/03/18/tda.htmlこの文章は各種スレッドの状態と分析についてよくまとめられている.