2016-06-21 82 views
1

我嘗試使用下面的代碼段一個線程獲得鎖:的ReentrantReadWriteLock未能得到鎖定,即使其狀態解鎖

Lock lock = readLock ? getLock(key).readLock() : getLock(key).writeLock(); 
try { 
    boolean locked = lock.tryLock(DEFAULT_TRY_TIME, DEFAULT_TRY_TIME_UNIT); //line 3 
    // If false, lock is not acquired 
    if (!locked) { 
     throw new TryLockTimeoutException(
       key + ": Failed to acquire " + lock + " within " + DEFAULT_TRY_TIME_STRING); 
    } 
} 

線30分鐘因此TryLockTimeoutException被拋出,錯誤爲後3點返回false :

com.concurrent.TryLockTimeoutException: keyIp : Failed to acquire [email protected]2cee[Unlocked] within 30MINUTES 
    at com.concurrent.NeAccessLockMap.acquireReadOrWriteLock(NeAccessLockMap.java:72) 

請注意,鎖狀態顯示爲錯誤解鎖。

我無法理解爲什麼會發生這種情況?即使鎖定空閒,爲什麼線程無法鎖定?

+1

鎖定讀鎖嗎? – tkausl

+0

它不會檢查讀/寫鎖嗎? – Batty

+0

我不確定,但我不這麼認爲。爲什麼它應該在寫鎖上打印'Locked',當它實際上是鎖定的鎖定,而不是寫鎖? – tkausl

回答

2

在您的示例中,您嘗試獲取寫入鎖定,但讀取鎖定已鎖定,這會阻止您獲取寫入鎖定。

因爲您可以獲取一個或多個讀取鎖定或獲取單個寫入鎖定,所以當存在讀取鎖定時,寫入鎖定將被標記爲Unlocked

試試下面的代碼:

ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); 
new Thread() { 
    @Override 
    public void run() { 
     readWriteLock.readLock().lock(); 
     try { 
      // block the read lock 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}.start(); 
if (!readWriteLock.writeLock().tryLock(1, TimeUnit.SECONDS)) { 
    System.out.println(readWriteLock); 
    System.out.println(readWriteLock.readLock()); 
    System.out.println(readWriteLock.writeLock()); 
} 

將有類似的輸出:

[email protected][Write locks = 0, Read locks = 1] 
[email protected]a04[Read locks = 1] 
[email protected]38a9[Unlocked]