Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Deadlock code explanation [duplicate]

Could someone please explain why the following code results in deadlock. My understanding is that when alphonse(thread) run then it acquires lock on friend obj because it invokes bow() method but how come gaston(another thread) is able to acquires the lock on the same friend obj while the alphonse haven't finished/released the lock on friend obj.

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.println("invoked by " + name);
        System.out.format("%s: %s"
            + "  has bowed to me!%n", 
            this.name, bower.getName());
        bower.bowBack(this);
        System.out.printf("finished by " + name);
    }
    public synchronized void bowBack(Friend bower) {
        System.out.format("%s: %s"
            + " has bowed back to me!%n",
            this.name, bower.getName());
        System.out.println("exiting bowBack()");
    }
}

public static void main(String[] args) throws InterruptedException {
    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();
}

}

like image 765
sol4me Avatar asked Dec 19 '22 12:12

sol4me


1 Answers

  1. thread 1: alphonse.bow(). To enter this method, thread 1 acquires the lock of alphonse, since the bow() method is synchronized.
  2. thread 2: gaston.bow(). To enter this method, thread 2 acquires the lock of gaston, since the bow() method is synchronized.
  3. thread 1: gaston.bowBack(). To enter this method, thread 1 needs to acquire the lock of gaston, since the bowBack() method is synchronized. It waits until thread 2 has released the lock of gaston
  4. thread 2: alphonse.bowBack(). To enter this method, thread 2 needs to acquire the lock of alphonse, since the bowBack() method is synchronized. It waits until thread 1 has released the lock of alphonse

The two threads end up waiting for each other. It's a deadlock.

like image 83
JB Nizet Avatar answered Jan 02 '23 20:01

JB Nizet