4

I am running a simple program which causes deadlock.

    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();

Below is the expected output

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

Now I fired jps command and found the PID for this java program and using jconsole <pid> command to view the deadlock.

Below is the stack trace in 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

Now my question is why jconsole stacktrace displaying different object's HexString ( java.lang.String@ )comparing to the values i am printing in first two sysout ?

More precisely why 6f3700d4 and 6823b3a values did not appear in jconsole output ?

bhdrkn
  • 6,244
  • 5
  • 35
  • 42
Santanu Sahoo
  • 1,137
  • 11
  • 29

1 Answers1

1

The problem is that String overrides hashCode. Use

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

for debugging.

Background: Object returns

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

in toString, but String and other classes override toString (with strings that would not be helpful in this context), therefore JConsole shows the info as it would have been shown by the original Object.toString.

lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • ok. Got it. I found https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode() and https://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier to research more. Thanks for the reply. – Santanu Sahoo Aug 27 '15 at 07:04