How does this cause deadlock

Question from blindspot23#4418

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());
            bower.bowBack(this);
        }
        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.


<- Index