java stacktrace 显示一个被阻塞的线程,但没有关于阻塞它的信息

Huy*_* Le 5 java synchronization stack-trace

有人能解释一下为什么在 jstack 捕获的热点的堆栈跟踪中,我看到一个线程被阻塞,而没有任何关于锁记录的信息,这意味着什么阻塞了它。

3 "ajp-0.0.0.0-8029-1082" daemon prio=10 tid=0x63721000 nid=0x2cba
waiting for monitor entry [0x4e619000]
4    java.lang.Thread.State: BLOCKED (on object monitor)
5         at java.lang.Class.forName0(Native Method)
6         at java.lang.Class.forName(Class.java:186)
7         at com.my.security.SecurityMethodInterceptor$Rule.isAllowed(SecurityMethodInterceptor.java:102)
8         at com.my.security.SecurityMethodInterceptor.isAllowed(SecurityMethodInterceptor.java:163)
9         at com.my.security.SecurityMethodInterceptor.invoke(SecurityMethodInterceptor.java:140)
Run Code Online (Sandbox Code Playgroud)

10 at ... 删除,因为它不相关

ysh*_*vit 0

在该堆栈中的某个位置,在您切断的部分中,类似于:

- waiting to lock <0xa3cd2188> (a java.lang.Object)
Run Code Online (Sandbox Code Playgroud)

尝试这个简单的应用程序,它有一个线程打印出它将要等待的线程,然后等待一段时间。然后,您可以kill -3 <pid>(在 Linux 上)获取其完整的线程转储,包括所有堆栈,包括等待线程的堆栈。

public class TTest {
    public static void main(String[] args) throws Exception {
        final Object lock = new Object();
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("Locking on: " + Integer.toString(lock.hashCode(), 16));
                synchronized (lock) {
                    System.out.println("Hello, world!");
                }   
            }   
        };  
        synchronized (lock) {
            thread.start();
            Thread.sleep(600 * 1000);
            System.out.println("bye!");
        }   
    }   
} 
Run Code Online (Sandbox Code Playgroud)

  • 如果它存在,那么“等待锁定”行将是紧随线程转储中顶部帧之后的行,就在“forName0()”调用之后。但它不在那里,它应该在那里。这就是这个问题的全部要点:为什么它丢失了? (2认同)