java - 使用 Jconsole 分析死锁

标签 java multithreading deadlock jconsole

我正在运行一个导致死锁的简单程序。

    final  String resource1 = "santanu";
    final String resource2 = "sahoo";
     System.out.println(Integer.toHexString(resource1.hashCode())    );
     System.out.println(Integer.toHexString(resource2.hashCode()) );

    Thread t1 = new Thread(){

        public void run()
        {
            synchronized (resource1) {
                System.out.println("Thread 1: locked resource 1");  
                try {

                    Thread.sleep(200);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (resource2) {
                     System.out.println("Thread 1: locked resource 2");     
                }               
            }
        }
    };
    Thread t2 = new Thread(){
        public void run()
        {
            synchronized (resource2) {
                try {
                     System.out.println("Thread 2: locked resource 2");  
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                                            e.printStackTrace();
                }
                synchronized (resource1) {
                     System.out.println("Thread 2: locked resource 1");  
                }
            }
        }
    };

    t1.start();
    t2.start();

下面是预期的输出

6f3700d4      
6823b3a        
Thread 1: locked resource 1
Thread 2: locked resource 2

现在我触发了jps 命令并找到了这个java 程序的PID 并使用jconsole <pid>查看死锁的命令。

下面是 jconsole 中的堆栈跟踪

Name: Thread-1
State: BLOCKED on java.lang.String@4ad61aef owned by: Thread-0
Total blocked: 1  Total waited: 1

Stack trace: 
 com.cmc.santanusol$2.run(santanusol.java:49)
   - locked java.lang.String@4406cef4

现在我的问题是,为什么 jconsole stacktrace 显示不同对象的 HexString (java.lang.String@) 与我在前两个 sysout 中打印的值相比?

更准确地说,为什么 6f3700d4 和 6823b3a 值没有出现在 jconsole 输出中?

最佳答案

问题是 String 覆盖了 hashCode。使用

System.out.println(Integer.toHexString(System.identityHashCode(resource1)));
System.out.println(Integer.toHexString(System.identityHashCode(resource2)));

用于调试。

背景:对象返回

getClass().getName() + "@" + Integer.toHexString(hashCode());

在 toString 中,但 String 和其他类会覆盖 toString(使用在此上下文中无用的字符串),因此 JConsole 显示的信息与原始 Object.toString 所显示的一样。

关于java - 使用 Jconsole 分析死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32241469/

相关文章:

java - 试图停止线程,但它又开始了

java - Swing 与继承

java - 在 WebSphere 下使用 Log4j 从 Spring 进行日志记录

java - 使用函数从 Java 8 中总和为给定数字的数组中查找一对整数

multithreading - 允许actor定期替换共享的不可变只读状态是 “ok”吗?

java - EntityUtils.toString() 中的间歇性死锁

sql-server - SQL Server 2005 : Key-Range Locks in Read Committed Transaction Isolation Level?

c - 随机运行实例的段错误

java - 创建类型 X 的通用字段并通过反射将其值设置为(不相关的)类型 Y 不会导致 IllegalArgumentException

java - hive :NoMatchingMethodException没有类的匹配方法