jstack是JDK自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息。
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。
Java堆栈跟踪工具jstack
语法
jstack [ option ] [ vmid ]
使用方式 | 说明 |
---|---|
jstack [ option ] pid | 查看当前时间点,指定进程的dump堆栈信息 |
jstack [ option ] pid > 文件 | 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中 |
jstack [ option ] executable core | 查看当前时间点,core文件的dump堆栈信息 |
jstack [ option ] [server_id@] |
查看当前时间点,远程机器的dump堆栈信息 |
option选项
选项 | 作用 |
---|---|
-F | 当进程挂起了,此时’jstack [-l] pid’是没有相应的,可使用此参数来强制打印堆栈信息 |
-m | 打印java和native c/c++框架的所有栈信息。一般排查不需要 |
-l | 除堆栈外,打印关于锁的附加信息。会使得JVM停顿得长久得多-l 建议不要用。一般情况不需要使用。 |
使用
jps查看java进程
work@authority-api-v1-66c44d77d6-8hhkv:~$ jps
132 Jps
47 authority-api.jar
jstack查看指定进程的当前堆栈情况
work@authority-api-v1-66c44d77d6-8hhkv:~$ jstack 47
2022-04-05 23:12:22
Full thread dump OpenJDK 64-Bit Server VM (25.222-b10 mixed mode):
"Attach Listener" #53 daemon prio=9 os_prio=0 tid=0x00007f3668001000 nid=0x98 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"http-nio-0.0.0.0-8081-exec-10" #52 daemon prio=5 os_prio=0 tid=0x00007f3608011800 nid=0x67 waiting on condition [0x00007f3630f86000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000e73b9c28> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8081-exec-9" #51 daemon prio=5 os_prio=0 tid=0x00007f3608010000 nid=0x66 waiting on condition [0x00007f3631087000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000e73b9c28> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
将指定进程的当前堆栈情况记录到某个文件中:
work@authority-api-v1-66c44d77d6-8hhkv:~$ jstack 47 > /home/work/wangql.txt
work@authority-api-v1-66c44d77d6-8hhkv:~$
jstack实战之高cpu占用率排查
测试代码:
package com.tudou.util;
import lombok.Synchronized;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class JstackTest {
public static Executor executor = Executors.newFixedThreadPool(5);
public static Object lock = new Object();
public static void main(String[] args) {
Task task1 = new Task();
Task task2 = new Task();
executor.execute(task1);
executor.execute(task2);
}
static class Task implements Runnable {
@Override
public void run() {
synchronized(lock) {
Calculate();
}
}
public void Calculate() {
int i = 0;
while(true) {
i++;
}
}
}
}
top命令查看各个进程的cpu使用情况,默认按cpu使用率排序
work@authority-web-v1-7688dc9bf7-kr48z:~$ top
top - 23:06:56 up 302 days, 7:36, 0 users, load average: 8.21, 8.46, 7.72
Tasks: 7 total, 1 running, 6 sleeping, 0 stopped, 0 zombie
%Cpu(s): 6.5 us, 1.8 sy, 0.0 ni, 90.9 id, 0.7 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem : 19706059+total, 5289860 free, 71409256 used, 12036147+buff/cache
KiB Swap: 0 total, 0 free, 0 used. 12377960+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
47 work 20 0 5003608 332432 16292 S 47.3 0.2 1:24.66 java
1 work 20 0 4280 692 628 S 0.0 0.0 0:01.44 sh
6 work 20 0 19728 3112 2804 S 0.0 0.0 0:00.00 bootstrap
16 work 20 0 19880 3204 2756 S 0.0 0.0 0:00.00 authority-web.j
1552 work 20 0 21116 4484 2984 S 0.0 0.0 0:00.02 bash
5218 work 20 0 21028 4676 3048 S 0.0 0.0 0:00.01 bash
5537 work 20 0 42812 3408 2908 R 0.0 0.0 0:00.01 top
从上图中可以看出pid为47的java进程占用了较多的cpu资源;
通过
top -Hp 47
可以查看该进程下各个线程的cpu使用情况
work@authority-web-v1-7688dc9bf7-kr48z:~$ top -Hp 47
top - 23:07:51 up 302 days, 7:37, 0 users, load average: 6.47, 7.91, 7.58
Threads: 48 total, 1 running, 47 sleeping, 0 stopped, 0 zombie
%Cpu(s): 5.7 us, 1.3 sy, 0.0 ni, 91.7 id, 1.1 wa, 0.0 hi, 0.2 si, 0.0 st
KiB Mem : 19706059+total, 4971968 free, 71714896 used, 12037372+buff/cache
KiB Swap: 0 total, 0 free, 0 used. 12350040+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5433 work 20 0 5070172 332464 16292 R 46.8 0.2 0:53.10 pool-4-thread-1
1266 work 20 0 5070172 332464 16292 S 0.3 0.2 0:00.17 Abandoned conne
47 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 java
48 work 20 0 5070172 332464 16292 S 0.0 0.2 0:13.52 java
49 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.88 java
50 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.92 java
51 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.08 java
52 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.09 java
53 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.52 java
54 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.37 VM Thread
55 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.01 Reference Handl
56 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.03 Finalizer
57 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 Surrogate Locke
58 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 Signal Dispatch
59 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 server-timer
61 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.03 Thread-2
62 work 20 0 5070172 332464 16292 S 0.0 0.2 0:23.11 C2 CompilerThre
63 work 20 0 5070172 332464 16292 S 0.0 0.2 0:06.03 C1 CompilerThre
64 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.13 Service Thread
65 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.41 VM Periodic Tas
69 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 Log4j2-Log4j2Sc
74 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 commons-pool-Ev
75 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 Timer-0
76 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 ContainerBackgr
77 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 container-0
78 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 Thread-6
79 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.00 pool-9-thread-1
80 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.06 pool-10-thread-
81 work 20 0 5070172 332464 16292 S 0.0 0.2 0:03.46 redisMessageLis
110 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.03 pool-13-thread-
160 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.03 NioBlockingSele
170 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.06 http-nio-0.0.0.
184 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.03 http-nio-0.0.0.
185 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.02 http-nio-0.0.0.
186 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.39 http-nio-0.0.0.
196 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.16 http-nio-0.0.0.
293 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.29 http-nio-0.0.0.
388 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.05 http-nio-0.0.0.
402 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.06 http-nio-0.0.0.
495 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.11 http-nio-0.0.0.
612 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.75 http-nio-0.0.0.
651 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.12 http-nio-0.0.0.
846 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.11 http-nio-0.0.0.
973 work 20 0 5070172 332464 16292 S 0.0 0.2 0:00.10 http-nio-0.0.0.
上图中可以看出pid为5433的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。
拿到线程的16进制
work@authority-web-v1-7688dc9bf7-kr48z:~$ printf "%x" 5433
1539
work@authority-web-v1-7688dc9bf7-kr48z:~$
jstack命令生成的thread dump信息包含了JVM中所有存活的线程,为了分析指定线程,必须找出对应线程的调用栈,应该如何找?
在top命令中,已经获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread dump中每个线程都有一个nid,找到对应的nid即可;隔段时间再执行一次stack命令获取thread dump,区分两份dump是否有差别,在nid=0x1539的线程调用栈中,发现该线程一直在执行HealthController类第48行的calculate方法,得到这个信息,就可以检查对应的代码是否有问题。
work@authority-web-v1-7688dc9bf7-kr48z:~$ jstack 47
2022-04-06 23:11:42
Full thread dump OpenJDK 64-Bit Server VM (25.222-b10 mixed mode):
"Attach Listener" #7763 daemon prio=9 os_prio=0 tid=0x00007fba44002000 nid=0x1ec2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"pool-4-thread-2" #5355 prio=5 os_prio=0 tid=0x00007fba00016000 nid=0x153a waiting for monitor entry [0x00007fb9dbdfc000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.rrc.authority.web.controller.HealthController$Task.run(HealthController.java:41)
- waiting to lock <0x00000000fbe5dd70> (a java.lang.Object)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"pool-4-thread-1" #5354 prio=5 os_prio=0 tid=0x00007fba0000b000 nid=0x1539 runnable [0x00007fb9db5f6000]
java.lang.Thread.State: RUNNABLE
at com.rrc.authority.web.controller.HealthController$Task.Calculate(HealthController.java:48)
at com.rrc.authority.web.controller.HealthController$Task.run(HealthController.java:41)
- locked <0x00000000fbe5dd70> (a java.lang.Object)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"Okio Watchdog" #4584 daemon prio=5 os_prio=0 tid=0x00007fb9c8237800 nid=0x1223 in Object.wait() [0x00007fb9db1f4000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at okio.AsyncTimeout.awaitTimeout(AsyncTimeout.java:338)
- locked <0x00000000fa902db0> (a java.lang.Class for okio.AsyncTimeout)
at okio.AsyncTimeout$Watchdog.run(AsyncTimeout.java:313)
"Abandoned connection cleanup thread" #1216 daemon prio=5 os_prio=0 tid=0x00007fb9c8134000 nid=0x4f2 in Object.wait() [0x00007fb9dbbfa000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000fd104958> (a java.lang.ref.ReferenceQueue$Lock)
at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)
"Tomcat JDBC Pool Cleaner[1112280004:1649256969328]" #1215 daemon prio=5 os_prio=0 tid=0x00007fb9c804d800 nid=0x4f1 in Object.wait() [0x00007fb9db9f8000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000000fd104970> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"http-nio-0.0.0.0-8088-exec-10" #923 daemon prio=5 os_prio=0 tid=0x00007fb9e4018800 nid=0x3cd waiting on condition [0x00007fb9dbaf9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-9" #796 daemon prio=5 os_prio=0 tid=0x00007fb9e4027800 nid=0x34e waiting on condition [0x00007fb9dbefd000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-8" #601 daemon prio=5 os_prio=0 tid=0x00007fb9e4026800 nid=0x28b waiting on condition [0x00007fba24960000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-7" #562 daemon prio=5 os_prio=0 tid=0x00007fb9e4025800 nid=0x264 waiting on condition [0x00007fb9dbcfb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-6" #445 daemon prio=5 os_prio=0 tid=0x00007fb9e4024800 nid=0x1ef waiting on condition [0x00007fb9dbffe000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-5" #352 daemon prio=5 os_prio=0 tid=0x00007fb9e4023800 nid=0x192 waiting on condition [0x00007fba24d64000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-4" #338 daemon prio=5 os_prio=0 tid=0x00007fb9e4022800 nid=0x184 waiting on condition [0x00007fba24c63000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-3" #243 daemon prio=5 os_prio=0 tid=0x00007fb9e4021800 nid=0x125 waiting on condition [0x00007fba2415a000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-exec-2" #146 daemon prio=5 os_prio=0 tid=0x00007fb9e4021000 nid=0xc4 waiting on condition [0x00007fba2475e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"DestroyJavaVM" #136 prio=5 os_prio=0 tid=0x00007fba8400d800 nid=0x30 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"http-nio-0.0.0.0-8088-exec-1" #135 daemon prio=5 os_prio=0 tid=0x00007fb9e4029000 nid=0xba waiting on condition [0x00007fba2425b000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd1049a0> (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 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-AsyncTimeout" #133 daemon prio=5 os_prio=0 tid=0x00007fba855a2800 nid=0xb9 waiting on condition [0x00007fba24a61000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1137)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-Acceptor-0" #132 daemon prio=5 os_prio=0 tid=0x00007fba855a2000 nid=0xb8 runnable [0x00007fba24b62000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x00000000fd0fd220> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:456)
at java.lang.Thread.run(Thread.java:748)
"http-nio-0.0.0.0-8088-ClientPoller-0" #118 daemon prio=5 os_prio=0 tid=0x00007fba84fcc800 nid=0xaa runnable [0x00007fba2445d000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000fd0fd088> (a sun.nio.ch.Util$3)
- locked <0x00000000fd0fd070> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000fd1380b8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:790)
at java.lang.Thread.run(Thread.java:748)
"NioBlockingSelector.BlockPoller-1" #108 daemon prio=5 os_prio=0 tid=0x00007fba85611800 nid=0xa0 runnable [0x00007fba2435c000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000fd0fcef0> (a sun.nio.ch.Util$3)
- locked <0x00000000fd0fced8> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000fd138148> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:339)
"pool-13-thread-1" #58 prio=5 os_prio=0 tid=0x00007fba857a6000 nid=0x6e waiting on condition [0x00007fba2485f000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fd0e8a68> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"redisMessageListenerContainer-1" #29 prio=5 os_prio=0 tid=0x00007fba85612800 nid=0x51 runnable [0x00007fba24e65000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:127)
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:195)
at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:141)
at redis.clients.jedis.Protocol.read(Protocol.java:205)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:242)
at redis.clients.jedis.BinaryJedisPubSub.process(BinaryJedisPubSub.java:87)
at redis.clients.jedis.BinaryJedisPubSub.proceedWithPatterns(BinaryJedisPubSub.java:75)
at redis.clients.jedis.BinaryJedis.psubscribe(BinaryJedis.java:2989)
at org.springframework.data.redis.connection.jedis.JedisConnection.pSubscribe(JedisConnection.java:3050)
at org.springframework.data.redis.listener.RedisMessageListenerContainer$SubscriptionTask.eventuallyPerformSubscription(RedisMessageListenerContainer.java:779)
at org.springframework.data.redis.listener.RedisMessageListenerContainer$SubscriptionTask.run(RedisMessageListenerContainer.java:746)
at java.lang.Thread.run(Thread.java:748)
"pool-10-thread-1" #28 prio=5 os_prio=0 tid=0x00007fba85cc4000 nid=0x50 waiting on condition [0x00007fba25166000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fc9a1f00> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"pool-9-thread-1" #27 prio=5 os_prio=0 tid=0x00007fba84ebd000 nid=0x4f waiting on condition [0x00007fba483f9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fc8f1d50> (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 java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:492)
at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:680)
at sun.nio.fs.AbstractWatchService.take(AbstractWatchService.java:118)
at com.renrenche.config.refresh.LocalMonitor.watchFile(LocalMonitor.java:57)
at com.renrenche.config.refresh.LocalMonitor.run(LocalMonitor.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"Thread-6" #26 daemon prio=5 os_prio=0 tid=0x00007fba85ca9000 nid=0x4e runnable [0x00007fba26eea000]
java.lang.Thread.State: RUNNABLE
at sun.nio.fs.LinuxWatchService.poll(Native Method)
at sun.nio.fs.LinuxWatchService.access$600(LinuxWatchService.java:47)
at sun.nio.fs.LinuxWatchService$Poller.run(LinuxWatchService.java:314)
at java.lang.Thread.run(Thread.java:748)
"container-0" #25 prio=5 os_prio=0 tid=0x00007fba84c78800 nid=0x4d waiting on condition [0x00007fba268e6000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:427)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer$1.run(TomcatEmbeddedServletContainer.java:166)
"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" #24 daemon prio=5 os_prio=0 tid=0x00007fba84734000 nid=0x4c waiting on condition [0x00007fba269e7000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1339)
at java.lang.Thread.run(Thread.java:748)
"Timer-0" #23 daemon prio=5 os_prio=0 tid=0x00007fba1c3b5000 nid=0x4b in Object.wait() [0x00007fba26de9000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000000fa673d48> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"commons-pool-EvictionTimer" #22 daemon prio=5 os_prio=0 tid=0x00007fba1c09e000 nid=0x4a in Object.wait() [0x00007fba26ce8000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000000fa394b50> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"Log4j2-Log4j2Scheduled-3" #17 daemon prio=5 os_prio=0 tid=0x00007fba848b3800 nid=0x45 waiting on condition [0x00007fba486fa000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fa48b5e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #12 daemon prio=9 os_prio=0 tid=0x00007fba84268000 nid=0x40 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread1" #11 daemon prio=9 os_prio=0 tid=0x00007fba8425b000 nid=0x3f waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #10 daemon prio=9 os_prio=0 tid=0x00007fba8425a800 nid=0x3e waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-2" #9 daemon prio=5 os_prio=0 tid=0x00007fba38001000 nid=0x3d runnable [0x00007fba6c1d5000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000f98c50b0> (a sun.nio.ch.Util$3)
- locked <0x00000000f98c5098> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000f98c6de0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:352)
at java.lang.Thread.run(Thread.java:748)
"server-timer" #7 daemon prio=5 os_prio=0 tid=0x00007fba84243800 nid=0x3b in Object.wait() [0x00007fba6c3d7000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000000f98e5f90> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"Signal Dispatcher" #5 daemon prio=9 os_prio=0 tid=0x00007fba84126000 nid=0x3a runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Surrogate Locker Thread (Concurrent GC)" #4 daemon prio=9 os_prio=0 tid=0x00007fba84124800 nid=0x39 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fba840f0800 nid=0x38 in Object.wait() [0x00007fba6ceb2000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000f9a8b6f8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fba840ee000 nid=0x37 in Object.wait() [0x00007fba6cfb3000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000f9a8b728> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=0 tid=0x00007fba840e4000 nid=0x36 runnable
"Gang worker#0 (Parallel GC Threads)" os_prio=0 tid=0x00007fba8401e800 nid=0x31 runnable
"Gang worker#1 (Parallel GC Threads)" os_prio=0 tid=0x00007fba84020000 nid=0x32 runnable
"Concurrent Mark-Sweep GC Thread" os_prio=0 tid=0x00007fba84051000 nid=0x35 runnable
"Gang worker#0 (Parallel CMS Threads)" os_prio=0 tid=0x00007fba8404d800 nid=0x33 runnable
"Gang worker#1 (Parallel CMS Threads)" os_prio=0 tid=0x00007fba8404f000 nid=0x34 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007fba8426a800 nid=0x41 waiting on condition
JNI global references: 351
work@authority-web-v1-7688dc9bf7-kr48z:~$
很明显:线程1获取到锁,处于RUNNABLE状态,线程2处于BLOCK状态
1、locked <0x00000000fbe5dd70>
说明线程1对地址为0x00000000fbe5dd70对象进行了加锁;
2、waiting to lock <0x00000000fbe5dd70>
说明线程2在等待地址为0x00000000fbe5dd70对象上的锁;
3、waiting for monitor entry [0x00007fb9dbdfc000]
说明线程1是通过synchronized关键字进入了监视器的临界区,并处于”Entry Set”队列,等待monitor。
测试代码
package com.tudou.util;
import lombok.Synchronized;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class JstackTest {
public static Executor executor = Executors.newFixedThreadPool(5);
public static Object lock = new Object();
public static void main(String[] args) {
Task task1 = new Task();
Task task2 = new Task();
executor.execute(task1);
executor.execute(task2);
}
static class Task implements Runnable {
@Override
public void run() {
synchronized(lock) {
//Calculate();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void Calculate() {
int i = 0;
while(true) {
i++;
}
}
}
}
线程1和2都处于WAITING状态
1、线程1和2都是先locked <0x000000076bf62500>
,再waiting on <0x000000076bf62500>
,之所以先锁再等同一个对象,是因为wait方法需要先通过synchronized获得该地址对象的monitor;
2、waiting on <0x000000076bf62500>
说明线程执行了wait方法之后,释放了monitor,进入到”Wait Set”队列,等待其它线程执行地址为0x000000076bf62500对象的notify方法,并唤醒自己。
jstack Dump 日志文件中的线程状态
dump 文件里,值得关注的线程状态有:
- 死锁,Deadlock(重点关注)
- 执行中,Runnable
- 等待资源,Waiting on condition(重点关注)
- 等待获取监视器,Waiting on monitor entry(重点关注)
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 阻塞,Blocked(重点关注)
- 停止,Parked
引用