我正在运行一个导致死锁的简单程序。
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 显示的信息相同。