java - Understanding why deadlock happens in this implementation -


i new multithreading, , came across example:

public class testthread {    public static object lock1 = new object();    public static object lock2 = new object();     public static void main(string args[]) {        threaddemo1 t1 = new threaddemo1();       threaddemo2 t2 = new threaddemo2();       t1.start();       t2.start();    }     private static class threaddemo1 extends thread {       public void run() {          synchronized (lock1) {             system.out.println("thread 1: holding lock 1...");             try { thread.sleep(10); }             catch (interruptedexception e) {}             system.out.println("thread 1: waiting lock 2...");             synchronized (lock2) {                system.out.println("thread 1: holding lock 1 & 2...");             }          }       }    }    private static class threaddemo2 extends thread {       public void run() {          synchronized (lock2) {             system.out.println("thread 2: holding lock 2...");             try { thread.sleep(10); }             catch (interruptedexception e) {}             system.out.println("thread 2: waiting lock 1...");             synchronized (lock1) {                system.out.println("thread 2: holding lock 1 & 2...");             }          }       }    }  } 

this causes following sample output:

thread 1: holding lock 1... thread 2: holding lock 2... thread 1: waiting lock 2... thread 2: waiting lock 1... 

i.e, there deadlock. however, if change order of locks obtained in second thread looks now:

public class testthread {    public static object lock1 = new object();    public static object lock2 = new object();     public static void main(string args[]) {        threaddemo1 t1 = new threaddemo1();       threaddemo2 t2 = new threaddemo2();       t1.start();       t2.start();    }     private static class threaddemo1 extends thread {       public void run() {          synchronized (lock1) {             system.out.println("thread 1: holding lock 1...");             try { thread.sleep(10); }             catch (interruptedexception e) {}             system.out.println("thread 1: waiting lock 2...");             synchronized (lock2) {                system.out.println("thread 1: holding lock 1 & 2...");             }          }       }    }    private static class threaddemo2 extends thread {       public void run() {          synchronized (lock1) {             system.out.println("thread 2: holding lock 1...");             try { thread.sleep(10); }             catch (interruptedexception e) {}             system.out.println("thread 2: waiting lock 2...");             synchronized (lock2) {                system.out.println("thread 2: holding lock 1 & 2...");             }          }       }    }  } 

it works expected, , sample output looks this:

thread 1: holding lock 1... thread 1: waiting lock 2... thread 1: holding lock 1 & 2... thread 2: holding lock 1... thread 2: waiting lock 2... thread 2: holding lock 1 & 2... 

can explain me happening in first 1 causing deadlock, , why change in second code fix it?

here's possible scenario first case:

thread 1 acquires lock1 , goes sleep 10 milliseconds. thread 2 acquires lock2 , goes sleep 10 milliseconds.

now thread 1 tries acquire lock2, can't since it's acquired thread 2, while thread 2 tries lock1 locked thread 1.

in second case, let's assume first thread picked run. gets lock1, while other thread blocked because it's trying lock1 well. thread 1 goes sleep, , proceed second (nested) synchronized block. tries (because it's still free) - got 2 locks. other thread still blocked.

only after finishes execution, releases both locks (since exit synchronized block), , jvm free decide thread pick, doesn't matter, same logic happens.


Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -