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
Post a Comment