Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is the lock released if I return from the synchronized block?

I am confused over the point at which the lock is released if I have a return statement from the synchronized block; to find that out I have added try-finally block and added a sysout inside finally block printing 'lock released' but I can clearly see that before even that 'release' statement is printed, the 2nd thread has already obtained the lock. When is the lock released? what is the guarantee that things don't get messier?

public static int testClassLevelMonitor() throws InterruptedException {
    try {
    synchronized(TestLocks.class) {
        System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- have the lock");
        Thread.currentThread().sleep(1000);
        return 0;
    }
    } finally {
        System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- released the lock");
        System.out.println("\n\n");
    }
}

Static Block : Thread pool-1-thread-1 -- have the lock

Static Block : Thread pool-1-thread-2 -- have the lock

Static Block : Thread pool-1-thread-1 -- released the lock

Static Block : Thread pool-1-thread-2 -- released the lock

like image 665
Venkatesh Laguduva Avatar asked Jan 05 '23 17:01

Venkatesh Laguduva


1 Answers

The synchronized statement is specified in the Java Language Specification.

SynchronizedStatement:  
    synchronized ( Expression ) Block 
  • [..]
  • Otherwise, let the non-null value of the Expression be V. The executing thread locks the monitor associated with V. Then the Block is executed, and then there is a choice:
    • If execution of the Block completes normally, then the monitor is unlocked and the synchronized statement completes normally.
    • If execution of the Block completes abruptly for any reason, then the monitor is unlocked and the synchronized statement completes abruptly (return completes abruptly) for the same reason.

In other words, the lock is only held for the length of the body of the synchronized statement.

System.out.println("Static Block : Thread " + Thread.currentThread().getName() + " -- have the lock");
Thread.currentThread().sleep(1000);
return 0;

The finally block will execute without holding the lock.


While holding the lock, the executing thread will push the result of evaluating the return statement onto the stack, release the lock, execute the finally block, then return the value.

like image 187
Sotirios Delimanolis Avatar answered Jan 14 '23 15:01

Sotirios Delimanolis