如果从同步块返回,锁什么时候释放?

Tec*_*kie 3 java multithreading locking

如果我有来自同步块的return语句,那么我对释放锁的点感到困惑;为了发现这个问题,我添加了try-finally块,并在finally块中添加了一个sysout打印“锁定释放”,但是我可以清楚地看到,即使在打印“ release”语句之前,第二个线程也已经获得了锁定。锁何时释放?什么可以保证事情不会变得更加混乱?

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

静态块:线程池-1-线程-1-具有锁定

静态块:线程池-1-线程2-具有锁定

静态块:线程池-1-线程-1-释放锁

静态块:线程池-1-线程-2-释放了锁

Sot*_*lis 5

synchronized语句在Java Language Specification中指定。

SynchronizedStatement:  
    synchronized ( Expression ) Block 
Run Code Online (Sandbox Code Playgroud)
  • [..]
  • 否则,将Expressionbe 的非空值设为V。执行线程锁定与关联的监视器V。然后Block 执行,然后有一个选择:
    • 如果执行Block正常完成,则监视器将解锁并且该synchronized语句将正常完成。
    • 如果Block由于某种原因突然完成了执行,则监视器将被解除锁定,并且由于相同的原因,synchronized语句将突然return完成(突然完成)。

换句话说,该锁仅在synchronized语句主体的整个长度内保持。

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

finally块将在不持有锁的情况下执行。


在持有锁的同时,正在执行的线程会将评估return语句的结果压入堆栈,释放锁,执行该finally块,然后返回该值。