Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How this java code produces deadlock?

i am going through oracle docs for deadlock.. i found this code

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();
    }
}

I am failing to understand, in what case deadlock will happen?

I run this code, it works fine. So there must be some special event, when deadlock will happen?

Suppose bow is called on alphonse object first, will it leave its lock on alphonse object when bower.bowBack(this) is called on bower object? Because if it retains its lock, bow function on another object will not get lock until alphonse leave its lock, and it will never be a deadlock situation..

like image 245
Sunny Avatar asked Jun 15 '26 09:06

Sunny


2 Answers

If you put a Thread.sleep(1000) after printing the first line and before making the call to bowBack, you should see a deadlock. This deadlock can happen anyway, it's will be rare.

You have two threads and two locks being acquired is different orders. This can leave each thread holding one lock but unable to get the second lock. i.e. a deadlock.

Note: threads take a lot of time to start which means the first thread can run to completion before the second one starts, so it is unlikely you will see the problem.


Here is a puzzler for you. This creates a deadlock, can you see why?

class A {
    static final int i;
    static {
        i = 128;

        Thread t = new Thread() {
            public void run() {
                System.out.println("i=" + i);
            }
        };
        t.start();
        try {
           t.join();
        } catch (InterruptedException e) {
           Thread.currentThread().interrupt();
        }
    }
like image 173
Peter Lawrey Avatar answered Jun 17 '26 22:06

Peter Lawrey


You have 2 objects, alphonse and gaston and 2 threads, Thread1 and Thread2

Suppose this happens:

  1. Thread1: alphonse enters the bow() method. and will hold a lock on the alphonse object

  2. Thread2: gaston enters the bow() method. and will hold a lock on the gaston object

  3. Thread1: alphonse while in the bow() method, calls bowBack() on the gaston object.

    -> Thread1 will block, since Thread2 already has the lock on gaston

  4. Thread2: gaston while in the bow() method, calls bowBack() on the alphonse object.

    -> Thread2 will block, since Thread1 already has the lock on alphonse

So now Thread1 is waiting for Thread2. And Thread2 is waiting for Thread1. This is a deadlock.

like image 43
nos Avatar answered Jun 17 '26 23:06

nos