0

I have an exaple from oracle.com, but I don't understand it.. Please, explain me. One thread run bow, then it run bowback but why nothing has printed?

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();
    }
}
Boris Mitioglov
  • 1,092
  • 4
  • 16
  • 32

2 Answers2

3

Depends on the timing. Each thread enters bow, and locks that object to that thread. Then, inside that synchronized method, it attempts to call bowBack on the other object. But that method is synchronized, and the object is locked to the other thread. So both threads sit there waiting for the other object monitor to release, which never happens. Hence, deadlock.

Again, this really depends on timing. If the first thread finishes before the second one starts, it will work fine.

3

Here's a scenario leading to a deadlock:

  • thread 1 calls alphonse.bow() and thus gets alphonse's lock
  • thread 2 calls gaston.bow() and thus gets gaston's lock
  • thread 1 wants to call gaston.bowBack(), but blocks until gaston's lock is released
  • thread 2 wants to call alphonse.bowBack(), but blocks until alphonse's lock is released

So both threads wait for each other infinitely.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • If thread invoke a synchronized method, it lock whole object? – Boris Mitioglov Sep 04 '13 at 21:05
  • 1
    Yes. To invoke a synchronized method of an object, the thread needs to acquire the object's lock. And once it's acquired, no other thread can acquire it until it's released (when the synchronized method returns, in this case) – JB Nizet Sep 04 '13 at 21:11
  • 1
    If you need more fine-tuned control, you can use the Concurrency framework introduced in Java 5 which contains `Lock` and object objects. You can have multiple locks per object, as well as other advanced features. –  Sep 04 '13 at 21:18
  • +1 JB. For posterity, it's important to realize that it is a race condition. The deadlock _may_ happen or may not. If you run it 10 times you might see the "Alphonse" message first or the "Gaston" message and then you might see the other message or the program may deadlock. – Gray Sep 04 '13 at 21:23