2015-08-27 93 views
3

我正在運行一個導致死鎖的簡單程序。使用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命令,發現PID爲這個java程序,並使用jconsole <pid>命令查看僵局。

下面是JConsole的

Name: Thread-1 
State: BLOCKED on [email protected] owned by: Thread-0 
Total blocked: 1 Total waited: 1 

Stack trace: 
com.cmc.santanusol$2.run(santanusol.java:49) 
    - locked [email protected] 

現在我的問題是堆棧跟蹤爲什麼JConsole的堆棧跟蹤顯示不同對象的十六進制串(java.lang.String中@)比較,我在頭兩個系統輸出打印值?

更確切地說,爲什麼6f3700d4和6823b3a值沒有出現在jconsole輸出中?

回答

1

問題是該字符串重寫hashCode。使用

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

用於調試。

背景:Object返回

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

,但字符串和其他類覆蓋的toString(用繩子將不會在這方面有幫助),因此JConsole的顯示信息,因爲這將被證明原始的Object.toString。

+0

好的。得到它了。我發現https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode()和https://stackoverflow.com/questions/299304/why-does-javas- hashcode-in-string-use-31-as-a-multiplier來研究更多。謝謝回覆。 –