Site Search:

ReentrancySynchronizer.java

<Back




In the following program, both sayHello() methods in SubClass and BaseClass are guarded by static final object demo. When thread-0 call demo.sayHello() and hold the lock, the lock demo's owner is thread 0 and the acquisition count is 1. Other threads (thread-1,2,3,4) that calls demo.sayHello() are blocked, and have to wait for thread 0 to release the lock.

After thread-0 executes 
    System.out.println(Thread.currentThread().getName() + " Hello");  
it is then executes
    super.sayHello();
super.sayHello() is guarded by demo object, and demo object is already held by a thread. 

If there is no reentrancy, thread-0 who calls super.sayHello() are blocked on lock demo, and have to wait for the owning thread to release the lock. The owning thread is thread 0 itself, which is blocked and waiting for a lock to release. So thread 0 will deadlock by itself. 

With reentrancy, the deadlock situation is broken. thread-0 who calls super.sayHello() didn't block on lock demo. Instead of waiting for owning thread (itself) to release the lock, JVM check the lock demo's owner, since the owner is thread 0, which is the same thread as the thread that acquiring the lock, the JVM keep the demo's owner unchanged and increase the lock demo's acquisition count to 2. JVM then claim thread 0's lock demo acquisition successful, so that thread 0 can execute super.sayHello(); 

After thread-0 executed
System.out.println(Thread.currentThread().getName() + " Hello from BaseClass");
it exits synchronized block in BaseClass, the lock demo's acquisition count decreases to 1, and the lock demo's owner is still thread-0. 

Thread-0 then exits synchronized block in SubClass, the lock demo's acquisition count decreases to 0, and the lock demo is released.

Thread-4 which blocking on the lock demo, now see lock demo is released, acquired the lock demo. JVM set lock demo's owner to Thread-4, increase lock demo's acquisition count to 1. The other threads which trying to acquire the lock demo are blocked and have to wait.


public class ReentrancySynchronizer implements Runnable{
    private static final SubClass demo = new SubClass();
    public static void main(String ... args) {
        for(int i = 0; i < 5; i++) {
            Thread th = new Thread(new ReentrancySynchronizer());
            th.start();
        }
    }
    public void run() {
        demo.sayHello();
    }
}

class SubClass extends BaseClass {
    public synchronized void sayHello() {
        System.out.println(Thread.currentThread().getName() + " Hello");
        super.sayHello();
    }
}

class BaseClass {
    public synchronized void sayHello() {
        System.out.println(Thread.currentThread().getName() + " Hello from BaseClass");
    }
}



concurrency>javac ReentrancySynchronizer.java 
concurrency>java ReentrancySynchronizer
Thread-0 Hello
Thread-0 Hello from BaseClass
Thread-4 Hello
Thread-4 Hello from BaseClass
Thread-3 Hello
Thread-3 Hello from BaseClass
Thread-2 Hello
Thread-2 Hello from BaseClass
Thread-1 Hello
Thread-1 Hello from BaseClass