How to Analyze Java Thread Dumps

When there is an obstacle, or when a Java based Web application is running much slower than expected, we need to use thread dumps. If thread dumps feel like very complicated to you, this article may help you very much. Here I will explain what threads are in Java, their types, how they are created, how to manage them, how you can dump threads from a running application, and finally how you can analyze them and determine the bottleneck or blocking threads. This article is a result of long experience in Java application debugging.

Java and Thread

A web server uses tens to hundreds of threads to process a large number of concurrent users. If two or more threads utilize the same resources, a contention between the threads is inevitable, and sometimes deadlock occurs.

Thread contention is a status in which one thread is waiting for a lock, held by another thread, to be lifted. Different threads frequently access shared resources on a web application. For example, to record a log, the thread trying to record the log must obtain a lock and access the shared resources.

Deadlock is a special type of thread contention, in which two or more threads are waiting for the other threads to complete their tasks in order to complete their own tasks.

Different issues can arise from thread contention. To analyze such issues, you need to use the thread dump. A thread dump will give you the information on the exact status of each thread.

Background Information for Java Threads

Thread Synchronization

A thread can be processed with other threads at the same time. In order to ensure compatibility when multiple threads are trying to use shared resources, one thread at a time should be allowed to access the shared resources by using thread synchronization.

Thread synchronization on Java can be done using monitor. Every Java object has a single monitor. The monitor can be owned by only one thread. For a thread to own a monitor that is owned by a different thread, it needs to wait in the wait queue until the other thread releases its monitor.

Thread Status

In order to analyze a thread dump, you need to know the status of threads. The statuses of threads are stated on java.lang.Thread.State.

Figure 1: Thread Status.

  • NEW: The thread is created but has not been processed yet.
  • RUNNABLE: The thread is occupying the CPU and processing a task. (It may be in WAITING status due to the OS‘s resource distribution.)
  • BLOCKED: The thread is waiting for a different thread to release its lock in order to get the monitor lock.
  • WAITING: The thread is waiting by using a wait, join or park method.
  • TIMED_WAITING: The thread is waiting by using a sleep, wait, join or park method. (The difference from WAITING is that the maximum waiting time is specified by the method parameter, and WAITING can be relieved by time as well as external changes.)

Thread Types

Java threads can be divided into two:

  1. daemon threads;
  2. and non-daemon threads.

Daemon threads stop working when there are no other non-daemon threads. Even if you do not create any threads, the Java application will create several threads by default. Most of them are daemon threads, mainly for processing tasks such as garbage collection or JMX.

A thread running the ‘static void main(String[] args)’ method is created as a non-daemon thread, and when this thread stops working, all other daemon threads will stop as well. (The thread running this main method is called the VM thread in HotSpot VM.)

Getting a Thread Dump

We will introduce the three most commonly used methods. Note that there are many other ways to get a thread dump. A thread dump can only show the thread status at the time of measurement, so in order to see the change in thread status, it is recommended to extract them from 5 to 10 times with 5-second intervals.

Getting a Thread Dump Using jstack

In JDK 1.6 and higher, it is possible to get a thread dump on MS Windows using jstack.

Use PID via jps to check the PID of the currently running Java application process.

view sourceprint?

1.[[email protected] ~]$ jps -v

2.

3.25780 RemoteTestRunner -Dfile.encoding=UTF-8

4.25590 sub.rmi.registry.RegistryImpl 2999 -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

5.26300 sun.tools.jps.Jps -mlvV -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

Use the extracted PID as the parameter of jstack to obtain a thread dump.

view sourceprint?

1.[[email protected] ~]$ jstack -f 5824

A Thread Dump Using jVisualVM

Generate a thread dump by using a program such as jVisualVM.

Figure 2:  A Thread Dump Using visualvm.

The task on the left indicates the list of currently running processes. Click on the process for which you want the information, and select the thread tab to check the thread information in real time. Click the Thread Dump button on the top right corner to get the thread dump file.

Generating in a Linux Terminal

Obtain the process pid by using ps -ef command to check the pid of the currently running Java process.

view sourceprint?

1.[[email protected] ~]$ ps - ef | grep java

2.

3.user      2477          1    0 Dec23 ?         00:10:45 ...

4.user    25780 25361   0 15:02 pts/3    00:00:02 ./jstatd -J -Djava.security.policy=jstatd.all.policy -p 2999

5.user    26335 25361   0 15:49 pts/3    00:00:00 grep java

Use the extracted pid as the parameter of kill –SIGQUIT(3) to obtain a thread dump.

Thread Information from the Thread Dump File

view sourceprint?

01."pool-1-thread-13" prio=6 tid=0x000000000729a000 nid=0x2fb4 runnable [0x0000000007f0f000] java.lang.Thread.State: RUNNABLE

02.at java.net.SocketInputStream.socketRead0(Native Method)

03.

04.at java.net.SocketInputStream.read(SocketInputStream.java:129)

05.

06.at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)

07.

08.at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)

09.

10.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

11.

12.- locked <0x0000000780b7e688> (a java.io.InputStreamReader)

13.

14.at java.io.InputStreamReader.read(InputStreamReader.java:167)

15.

16.at java.io.BufferedReader.fill(BufferedReader.java:136)

17.

18.at java.io.BufferedReader.readLine(BufferedReader.java:299)

19.

20.- locked <0x0000000780b7e688> (a java.io.InputStreamReader)

21.

22.at java.io.BufferedReader.readLine(BufferedReader.java:362)

)
  • Thread name: When using Java.lang.Thread class to generate a thread, the thread will be named Thread-(Number), whereas when using java.util.concurrent.ThreadFactory class, it will be named pool-(number)-thread-(number).
  • Priority: Represents the priority of the threads.
  • Thread ID: Represents the unique ID for the threads. (Some useful information, including the CPU usage or memory usage of the thread, can be obtained by using thread ID.)
  • Thread status: Represents the status of the threads.
  • Thread callstack: Represents the call stack information of the threads.

Thread Dump Patterns by Type

When Unable to Obtain a Lock (BLOCKED)

This is when the overall performance of the application slows down because a thread is occupying the lock and prevents other threads from obtaining it. In the following example, BLOCKED_TEST pool-1-thread-1 thread is running with <0x0000000780a000b0> lock, while BLOCKED_TEST pool-1-thread-2 and BLOCKED_TEST pool-1-thread-3 threads are waiting to obtain <0x0000000780a000b0> lock.

Figure 3: A thread blocking other threads.

view sourceprint?

01."BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]

02.java.lang.Thread.State: RUNNABLE

03.at java.io.FileOutputStream.writeBytes(Native Method)

04.at java.io.FileOutputStream.write(FileOutputStream.java:282)

05.at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)

06.at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)

07.- locked <0x0000000780a31778> (a java.io.BufferedOutputStream)

08.at java.io.PrintStream.write(PrintStream.java:432)

09.- locked <0x0000000780a04118> (a java.io.PrintStream)

10.at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)

11.at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)

12.at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)

13.- locked <0x0000000780a040c0> (a java.io.OutputStreamWriter)

14.at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)

15.at java.io.PrintStream.newLine(PrintStream.java:496)

16.- locked <0x0000000780a04118> (a java.io.PrintStream)

17.at java.io.PrintStream.println(PrintStream.java:687)

18.- locked <0x0000000780a04118> (a java.io.PrintStream)

19.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44)

20.- locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)

21.at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7)

22.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

23.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

24.at java.lang.Thread.run(Thread.java:662)

25.

26.Locked ownable synchronizers:

27.- <0x0000000780a31758> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

28.

29."BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000]

30.java.lang.Thread.State: BLOCKED (on object monitor)

31.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43)

32.- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)

33.at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26)

34.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

35.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

36.at java.lang.Thread.run(Thread.java:662)

37.

38.Locked ownable synchronizers:

39.- <0x0000000780b0c6a0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

40.

41."BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000]

42.java.lang.Thread.State: BLOCKED (on object monitor)

43.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:42)

44.- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)

45.at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34)

46.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886

47.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

48.at java.lang.Thread.run(Thread.java:662)

49.

50.Locked ownable synchronizers:

51.- <0x0000000780b0e1b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

When in Deadlock Status

This is when thread A needs to obtain thread B‘s lock to continue its task, while thread B needs to obtain thread A‘s lock to continue its task. In the thread dump, you can see that DEADLOCK_TEST-1 thread has 0x00000007d58f5e48 lock, and is trying to obtain 0x00000007d58f5e60 lock. You can also see that DEADLOCK_TEST-2 thread has 0x00000007d58f5e60 lock, and is trying to obtain 0x00000007d58f5e78 lock. Also, DEADLOCK_TEST-3 thread has 0x00000007d58f5e78 lock, and is trying to obtain 0x00000007d58f5e48 lock. As you can see, each thread is waiting to obtain another thread‘s lock, and this status will not change until one thread discards its lock.

Figure 4: Threads in a Deadlock status.

view sourceprint?

01."DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]

02.java.lang.Thread.State: BLOCKED (on object monitor)

03.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

04.- waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

05.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

06.- locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

07.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

08.

09.Locked ownable synchronizers:

10.- None

11.

12."DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]

13.java.lang.Thread.State: BLOCKED (on object monitor)

14.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

15.- waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

16.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

17.- locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

18.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

19.

20.Locked ownable synchronizers:

21.- None

22.

23."DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]

24.java.lang.Thread.State: BLOCKED (on object monitor)

25.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)

26.- waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

27.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)

28.- locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)

29.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

30.

31.Locked ownable synchronizers:

32.- None

When Continuously Waiting to Receive Messages from a Remote Server

The thread appears to be normal, since its state keeps showing as RUNNABLE. However, when you align the thread dumps chronologically, you can see that socketReadThread thread is waiting infinitely to read the socket.

Figure 5: Continuous Waiting Status.

view sourceprint?

01."socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]

02.java.lang.Thread.State: RUNNABLE

03.at java.net.SocketInputStream.socketRead0(Native Method)

04.at java.net.SocketInputStream.read(SocketInputStream.java:129)

05.at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)

06.at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)

07.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

08.- locked <0x00000007d78a2230> (a java.io.InputStreamReader)

09.at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)

10.- locked <0x00000007d78a2230> (a java.io.InputStreamReader)

11.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)

12.at java.io.InputStreamReader.read(InputStreamReader.java:151)

13.at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)

14.at java.lang.Thread.run(Thread.java:662)

When Waiting

The thread is maintaining WAIT status. In the thread dump, IoWaitThread thread keeps waiting to receive a message from LinkedBlockingQueue. If there continues to be no message for LinkedBlockingQueue, then the thread status will not change.

Figure 6: Waiting status.

view sourceprint?

01."IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]

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

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

04.- parking to wait for  <0x00000007d5c45850> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

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

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

07.at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)

08.at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)

09.at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)

10.at java.lang.Thread.run(Thread.java:662)

When Thread Resources Cannot be Organized Normally

Unnecessary threads will pile up when thread resources cannot be organized normally. If this occurs, it is recommended to monitor the thread organization process or check the conditions for thread termination.

Figure 7: Unorganized Threads.

How to Solve Problems by Using Thread Dump

Example 1: When the CPU Usage is Abnormally High

1. Extract the thread that has the highest CPU usage.

view sourceprint?

1.[[email protected] ~]$ ps -mo pid.lwp.stime.time.cpu -C java

2.

3.PID         LWP          STIME                  TIME        %CPU

4.10029               -         Dec07          00:02:02           99.5

5.-       10039        Dec07          00:00:00              0.1

6.-       10040        Dec07          00:00:00           95.5

From the application, find out which thread is using the CPU the most.

Acquire the Light Weight Process (LWP) that uses the CPU the most and convert its unique number (10039) into a hexadecimal number (0x2737).

2. After acquiring the thread dump, check the thread‘s action.

Extract the thread dump of an application with a PID of 10029, then find the thread with an nid of 0x2737.

view sourceprint?

01."NioProcessor-2" prio=10 tid=0x0a8d2800 nid=0x2737 runnable [0x49aa5000]

02.java.lang.Thread.State: RUNNABLE

03.at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)

04.at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)

05.at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)

06.at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)

07.- locked <0x74c52678> (a sun.nio.ch.Util$1)

08.- locked <0x74c52668> (a java.util.Collections$UnmodifiableSet)

09.- locked <0x74c501b0> (a sun.nio.ch.EPollSelectorImpl)

10.at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)

11.at external.org.apache.mina.transport.socket.nio.NioProcessor.select(NioProcessor.java:65)

12.at external.org.apache.mina.common.AbstractPollingIoProcessor$Worker.run(AbstractPollingIoProcessor.java:708)

13.at external.org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)

14.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

15.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

16.at java.lang.Thread.run(Thread.java:662)

Extract thread dumps several times every hour, and check the status change of the threads to determine the problem.

Example 2: When the Processing Performance is Abnormally Slow

After acquiring thread dumps several times, find the list of threads with BLOCKED status.

view sourceprint?

01." DB-Processor-13" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f000]

02.java.lang.Thread.State: BLOCKED (on object monitor)

03.at beans.ConnectionPool.getConnection(ConnectionPool.java:102)

04.- waiting to lock <0xe0375410> (a beans.ConnectionPool)

05.at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)

06.at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)

07.

08."DB-Processor-14" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f020]

09.java.lang.Thread.State: BLOCKED (on object monitor)

10.at beans.ConnectionPool.getConnection(ConnectionPool.java:102)

11.- waiting to lock <0xe0375410> (a beans.ConnectionPool)

12.at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)

13.at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)

14.

15." DB-Processor-3" daemon prio=5 tid=0x00928248 nid=0x8b waiting for monitor entry [0x000000000825d080]

16.java.lang.Thread.State: RUNNABLE

17.at oracle.jdbc.driver.OracleConnection.isClosed(OracleConnection.java:570)

18.- waiting to lock <0xe03ba2e0> (a oracle.jdbc.driver.OracleConnection)

19.at beans.ConnectionPool.getConnection(ConnectionPool.java:112)

20.- locked <0xe0386580> (a java.util.Vector)

21.- locked <0xe0375410> (a beans.ConnectionPool)

22.at beans.cus.Cue_1700c.GetNationList(Cue_1700c.java:66)

23.at org.apache.jsp.cue_1700c_jsp._jspService(cue_1700c_jsp.java:120)

Acquire the list of threads with BLOCKED status after getting the thread dumps several times.

If the threads are BLOCKED, extract the threads related to the lock that the threads are trying to obtain.

Through the thread dump, you can confirm that the thread status stays BLOCKED because <0xe0375410> lock could not be obtained. This problem can be solved by analyzing stack trace from the thread currently holding the lock.

There are two reasons why the above pattern frequently appears in applications using DBMS. The first reason is inadequate configurations. Despite the fact that the threads are still working, they cannot show their best performance because the configurations for DBCP and the like are not adequate. If you extract thread dumps multiple times and compare them, you will often see that some of the threads that were BLOCKED previously are in a different state.

The second reason is the abnormal connection. When the connection with DBMS stays abnormal, the threads wait until the time is out. In this case, even after extracting the thread dumps several times and comparing them, you will see that the threads related to DBMS are still in a BLOCKED state. By adequately changing the values, such as the timeout value, you can shorten the time in which the problem occurs.

Coding for Easy Thread Dump

Naming Threads

When a thread is created using java.lang.Thread object, the thread will be named Thread-(Number). When a thread is created using java.util.concurrent.DefaultThreadFactory object, the thread will be named pool-(Number)-thread-(Number). When analyzing tens to thousands of threads for an application, if all the threads still have their default names, analyzing them becomes very difficult, because it is difficult to distinguish the threads to be analyzed.

Therefore, you are recommended to develop the habit of naming the threads whenever a new thread is created.

When you create a thread using java.lang.Thread, you can give the thread a custom name by using the creator parameter.

view sourceprint?

1.public Thread(Runnable target, String name);

2.public Thread(ThreadGroup group, String name);

3.public Thread(ThreadGroup group, Runnable target, String name);

4.public Thread(ThreadGroup group, Runnable target, String name, long stackSize);

When you create a thread using java.util.concurrent.ThreadFactory, you can name it by generating your own ThreadFactory. If you do not need special functionalities, then you can use MyThreadFactory as described below:

view sourceprint?

01.import java.util.concurrent.ConcurrentHashMap;

02.import java.util.concurrent.ThreadFactory;

03.import java.util.concurrent.atomic.AtomicInteger;

04.

05.public class MyThreadFactory implements ThreadFactory {

06.private static final ConcurrentHashMap<String, AtomicInteger> POOL_NUMBER =

07.new ConcurrentHashMap<String, AtomicInteger>();

08.private final ThreadGroup group;

09.private final AtomicInteger threadNumber = new AtomicInteger(1);

10.private final String namePrefix;

11.

12.public MyThreadFactory(String threadPoolName) {

13.

14.if (threadPoolName == null) {

15.throw new NullPointerException("threadPoolName");

16.}

17.POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());

18.

19.SecurityManager securityManager = System.getSecurityManager();

20.group = (securityManager != null) ? securityManager.getThreadGroup() :

21.Thread.currentThread().getThreadGroup();

22.

23.AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);

24.

25.if (poolCount == null) {

26.namePrefix = threadPoolName + " pool-00-thread-";

27.else {

28.namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";

29.}

30.}

31.

32.public Thread newThread(Runnable runnable) {

33.Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);

34.

35.if (thread.isDaemon()) {

36.thread.setDaemon(false);

37.}

38.

39.if (thread.getPriority() != Thread.NORM_PRIORITY) {

40.thread.setPriority(Thread.NORM_PRIORITY);

41.}

42.

43.return thread;

44.}

45.}

Obtaining More Detailed Information by Using MBean

You can obtain ThreadInfo objects using MBean. You can also obtain more information that would be difficult to acquire via thread dumps, by using ThreadInfo.

view sourceprint?

01.ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();

02.long[] threadIds = mxBean.getAllThreadIds();

03.ThreadInfo[] threadInfos =

04.mxBean.getThreadInfo(threadIds);

05.

06.for (ThreadInfo threadInfo : threadInfos) {

07.System.out.println(

08.threadInfo.getThreadName());

09.System.out.println(

10.threadInfo.getBlockedCount());

11.System.out.println(

12.threadInfo.getBlockedTime());

13.System.out.println(

14.threadInfo.getWaitedCount());

15.System.out.println(

16.threadInfo.getWaitedTime());

17.}

You can acquire the amount of time that the threads WAITed or were BLOCKED by using the method in ThreadInfo, and by using this you can also obtain the list of threads that have been inactive for an abnormally long period of time.

In Conclusion

In this article I was concerned that for developers with a lot of experience in multi-thread programming, this material may be common knowledge, whereas for less experienced developers, I felt that I was skipping straight to thread dumps, without providing enough background information about the thread activities. This was because of my lack of knowledge, as I was not able to explain the thread activities in a clear yet concise manner. I sincerely hope that this article will prove helpful for many developers.

时间: 2024-10-12 11:02:10

How to Analyze Java Thread Dumps的相关文章

How to Analyze Java Thread Dumps--reference

原文地址:http://architects.dzone.com/articles/how-analyze-java-thread-dumps The Performance Zone is presented by AppDynamics. AppDynamics is a leaders in the APM space with massive cost reductions for users. The content of this article was originally wri

JAVA Thread Dumps 三部曲

一.windows环境下方法 1:cmd下找到运行服务器容器的PID jps -v 例: C:\Users\Administrator>jps -v4856 Bootstrap -Djdk.tls.ephemeralDHKeySize=2048 -Djava.util.logging.config.file=D:\soft\apache-tomcat-7.0.69\conf\logging.properties -Djava.util.logging.manager=org.apache.jul

三个实例演示 Java Thread Dump 日志分析

jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注)  执行中,Runnable 等待资源,Waiting on condition(重点关注) 等待获取监视器,Waiting on monitor entry(重点关注) 暂停,Suspended 对象等待中,Object.wait() 或 TIMED_WAITING 阻塞,Blocked(重点关注)   停止,Parked 下面我们先从第一个例子开始分析,然后再列出不同线程

三个实例演示 Java Thread Dump 日志分析(转)

原文链接:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html 转来当笔记^_^ jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注)  执行中,Runnable 等待资源,Waiting on condition(重点关注) 等待获取监视器,Waiting on monitor entry(重点关注) 暂停,Suspended 对象

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提

这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提: * 1.必须要有两个以上的线程,才需要同步. * 2.必须是多个线程使用同一个锁. * 3.必须保证同步中只能有一个线程在运行,锁加在哪一块代码 那么我们要思考的地方有:1.知道我们写的哪些是多线程代码 2.明确共享数据 3.明确多线程运行的代码中哪些语句是操作共享数据的.. 4.要确保使用同一个锁. 下面的代码:需求:两个存户分别往银行存钱,每次村100块,分三次存完. class bank{ private int

Java Thread.interrupt方法

部分内容引用CSDNdr8737010 比如你在main线程中,开启了一个新的线程new Thread 首先,每个线程内部都有一个boolean型变量表示线程的中断状态,true代表线程处于中断状态,false表示未处于中断状态. 而interrupt()方法的作用只是用来改变线程的中断状态(把线程的中断状态改为true,即被中断). A线程调用wait,sleep,join方法,这时B线程调用了A的interrupt方法而抛出的InterruptedException是wait,sleep,j