2015-05-15 49 views
1

的ReentrantLock的ReentrantLock - 解鎖在稱爲方法

void a() { 

    lock.lock(); //got intrinsic lock 
    System.out.println(Thread.currentThread().getName()); 
    System.out.println("In A"); 
    b();   // called method in synchronized block 

    Thread.sleep(2000); // sleeping current thread(avoided try catch for simplicity) 


    System.out.println("after calling method B()"); 
    System.out.println(Thread.currentThread().getName()); 

    lock.unlock(); // releasing intrinsic lock 

} 

void b() { 

    lock.lock();// getting intrinsic lock, no problem as calling thread already has intrinsic lock 
    System.out.println(Thread.currentThread().getName()); 
    System.out.println("In B"); 
    lock.unlock(); // intentionally releasing lock, so now there is no lock . 

     Thread.sleep(2000); 
} 

兩個線程派生Thread- 0和線程1兩者都調用()。

在()中,我得到了內部鎖,並且比我調用b()。在b()中,我也得到了內部鎖,所以我會得到當前線程擁有的同一個鎖。 現在我故意在b()中解鎖,釋放鎖以便其他等待的線程可以獲得鎖,以確保我甚至使當前線程休眠。當我的線程在b()中睡2000毫秒,而在()中爲2000毫秒時,我期待其他線程通過獲得釋放的鎖來運行()。

但它不會發生按我的輸出

輸出: -

Thread-0 
In A 
Thread-0 
In B 
after calling method B() 
Thread-0 
Thread-1 
In A 
Thread-1 
In B 
after calling method B() 
Thread-1 

回答

3

現在,我故意在B解鎖(),它釋放鎖,以便其他等待的線程可以得到鎖

不,它不會完全釋放它 - 它只是遞減鎖計數。在您撥打unlock之前,您已撥打lock兩次,因此保留計數爲2.在您撥打unlock後,保留計數爲1,因此它仍阻止其他線程獲取鎖定。基本上,你的代碼是一個有點像有:

void a() { 
    synchronized (foo) { 
     b(); 
    } 
} 

void b() { 
    synchronized(foo) { 
     // In here, the count is 2 
    } 
    // Now the count is still 1... 
} 
2

明白,鎖類的名稱是折返鎖定,這意味着相同的線程可以獲取該鎖多次這是非常重要的,但必須釋放相同的次數才能從監視器中出來。

在Java-8中引入了其他的鎖類,稱爲StampedLock,它不是可重入的,並且會有不同的行爲。