1. 程式人生 > >java丟擲異常物件鎖是否被釋放

java丟擲異常物件鎖是否被釋放

今天看了一下丟擲異常時鎖是否會被釋放的問題,我們先來看說明問題的程式

public class Main {

    class ThreadObj extends Thread{
        @Override
        public void run() {
            try {
                testSynMethod();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    String lockObj = "lockMe"
; void testSynMethod() throws InterruptedException{ synchronized(lockObj){ System.out.println(Thread.currentThread().getName()); //確保兩個另一執行緒也進入了此方法 Thread.currentThread().sleep(2000); throw new RuntimeException("i am an Exception"); } } public
static void main(String[] args) { Main m = new Main(); Main.ThreadObj t1 = m.new ThreadObj(); t1.setName("thread1"); Main.ThreadObj t2 = m.new ThreadObj(); t2.setName("thread2"); t1.start(); t2.start(); } }

程式碼很簡單,啟動了兩個執行緒執行同一個方法, 讓執行緒在獲取物件鎖之後丟擲異常,看另一個執行緒是否能獲取到物件的鎖來執行同步程式碼塊,程式列印的結果如下

thread1
thread2
Exception in thread "thread1" java.lang.RuntimeException: i am an Exception
    at com.pay.o2o.test.Main.testSynMethod(Main.java:22)
    at com.pay.o2o.test.Main$ThreadObj.run(Main.java:10)
Exception in thread "thread2" java.lang.RuntimeException: i am an Exception
    at com.pay.o2o.test.Main.testSynMethod(Main.java:22)
    at com.pay.o2o.test.Main$ThreadObj.run(Main.java:10)

從程式執行結果可以看到兩個執行緒都執行了同步操作,也就是說明在同步塊中丟擲異常,執行緒是會將同步鎖釋放的,而且我們還能瞭解到,釋放的速度是很快的,因為第二個執行緒在第一個執行緒列印丟擲的異常資訊之前就執行了列印執行緒名稱的程式碼。