public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void bow(Friend bower) { System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName()); .bowBack(this); bower} public synchronized void bowBack(Friend bower) { System.out.format("%s: %s" + " has bowed back to me!%n", this.name, bower.getName()); } } public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new Runnable() { public void run() { alphonse.bow(gaston); } }).start(); new Thread(new Runnable() { public void run() { gaston.bow(alphonse); } }).start(); } }
This is the example given for deadlock in java docs. I presume that inside the bow method, the last line causes the deadlock. But how? We access the bowBack method using the object and not the thread. Then why do we get a deadlock.
Those synchronized blocks basically make this
Thread 1:
- lock gaston
- lock alphonse
- unlock alphonse
- unlock gaston
Thread 2:
- lock alphonse
- lock gaston
- unlock gaston
- unlock alphonse
now we can write those out
1. lock gaston
1. lock alphonse
1. unlock alphonse
1. unlock gaston
2. lock alphonse
2. lock gaston
2. unlock gaston
2. unlock alphonse
and intermesh them like so
actually - exercise for you, how can those get ordered in a way that causes deadlock
Because bowBack method invocation inside bow method tries to get the lock of gaston, while a thread that tries to get the lock on gaston is already blocked and queued?
1. lock gaston
2. lock alphonse
1. lock alphonse
2. lock gaston
1. unlock alphonse
1. unlock gaston
2. unlock gaston
2. unlock alphonse
Basically this. I think your words are right.
Alright then, Thank you for the help.