0

in java tutorial i came to this simple example of a Deadlock, and for some reason can't figure out why it blocked

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());
            System.out.println("Nice try " + this.name);
            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();
    }
}

let's look to some real exemple

run:
Alphonse: Gaston  has bowed to me!
Gaston: Alphonse  has bowed to me!
Nice try Gaston
Nice try Alphonse

so both Alphonse and Gaston, now running "bow()", each one at the end of the "bow()" trying to call "bowBack()" on each other, "bowBack()" is no static, thus Alphonse and Gaston have separated instance of this method, also "bowBack()" wasn't called before, thus it shouldn't be blocked. So why ther is a Deadlock.

In a tutorial http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

it's explained as

When Deadlock runs, it's extremely likely that both threads will block when they 
attempt to invoke bowBack. Neither block will ever end, because each thread is 
waiting for the other to exit bow.

but why, to run "bowBack()" it should first wait the end of the "bow()", if they don't interfere with each other

Alphonse.bow()--->trying to call-->Gaston.bowBack()

Gaston.bow()--->trying to call-->Alphonse.bowBack()

BiScOtTiNo
  • 175
  • 11
  • possible duplicate of [Trying to wrap my wee brain around how threads deadlock](http://stackoverflow.com/questions/749641/trying-to-wrap-my-wee-brain-around-how-threads-deadlock) – Oleg Estekhin Jul 09 '14 at 12:32

1 Answers1

4

but why, to run "bowBack()" it should first wait the end of the "bow()", if they don't interfere with each other

When bowBack() is called - the lock that the running thread tries to acquire is the lock on the Object whose method it is trying to call.

Here - Alphonse is an object and Gaston is second object.

Alphonse.bow()--->trying to call-->Gaston.bowBack()

In above , the first call takes lock on Alphonse , and while that lock is still held , tries to aquire lock on Gaston.

So , in Thread 1 : Lock ( Alp) AND try to Lock( Gaston) WITHOUT RELEASING Lock(Apl)

Gaston.bow()--->trying to call-->Alphonse.bowBack()

In here , the first bow() aquires lock on Gaston object , and then tries to acquire lock on Alphonse.

So ,in Thread 2 : Lock ( Gaston) and try Lock(Apl) WITHOUT RELEASING Lock(Gaston)

If the first step in thread 1 and thread 2 are both complete , then you can work out that the second step can never complete - hence the Deadlock

Bhaskar
  • 7,443
  • 5
  • 39
  • 51