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

    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 堆栈跟踪显示不同对象的 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 显示的信息相同。

10-08 04:21