ReentrantLock中lock(),tryLock(),lockInterruptibly()的區別

lock()

兩個線程都使用lock獲取鎖,如果線程A獲取到了鎖,線程B只能等待,對線程B調用interrupt()方法不能中斷線程B的等待過程。

tryLock()

使用lock獲取鎖,如果線程A獲取到了鎖,線程A返回true,線程B直接返回false。可以傳入時間參數,表示拿不到鎖等待一段時間,這段時間內還是拿不到就返回false。

lockInterruptibly()

兩個線程都使用lockInterruptibly獲取鎖,如果線程A獲取到了鎖,線程B只能等待,對線程B調用interrupt()方法能夠中斷線程B的等待過程。

案例

如下示例中,t0得到了鎖,t1等待。在t1等待時,調用t1.interrupt(),中斷t1的等待。

public class ReentrantLockDemo {
 
    private Lock lock = new ReentrantLock();
 
    public void test() {
        String name = Thread.currentThread().getName();
        try {
            System.out.println(name + " 嘗試獲取鎖");
            lock.lockInterruptibly();
            Thread.sleep(1000);
            System.out.println(name + " 得到鎖");
        } catch (InterruptedException e) {
            System.out.println(name + " InterruptedException異常");
        } finally {
            try {
                lock.unlock();
                System.out.println(name + " 嘗試釋放鎖");
            } catch (Exception e) {
                System.out.println(name + " : 釋放鎖失敗(未獲取鎖的線程調用unlock)");
            }
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        ReentrantLockDemo lock = new ReentrantLockDemo();
        Thread t0 = new Thread(
                lock::test
        );
        Thread t1 = new Thread(
                lock::test
        );
        t0.start();
        Thread.sleep(10);
        t1.start();
        Thread.sleep(100);
        // 中斷等待中的t1的線程
        t1.interrupt();
    }
}

運行結果

Thread-0 嘗試獲取鎖
Thread-1 嘗試獲取鎖
Thread-1 InterruptedException異常
Thread-1 : 釋放鎖失敗(未獲取鎖的線程調用unlock)
Thread-0 得到鎖
Thread-0 嘗試釋放鎖

如果使用lock()方法獲取鎖,線程不會被中斷。將lock.lockInterruptibly()改爲lock.lock()。

運行結果

Thread-0 嘗試獲取鎖
Thread-1 嘗試獲取鎖
Thread-0 得到鎖
Thread-0 嘗試釋放鎖
Thread-1 lockInterruptibly的InterruptedException異常
Thread-1 嘗試釋放鎖

從案例中可以看出,使用lockInterruptibly方法時候會出現 釋放鎖失敗(未獲取鎖的線程調用unlock)的異常,而使用lock方法時不會出現這個異常。

原因

使用lockInterruptibly獲取鎖時,當它處於等待階段時直接被中斷,沒有獲取到鎖,所以調用unlock會發生異常。而使用lock獲取鎖時,當它處於等待階段時,中斷不了,等到線程0結束後,線程1得到鎖才被中斷,所以調用unlock時不會發生異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章