2016-09-06 112 views
1

我有一個任務,我需要實現一個鎖定機制。這是我迄今爲止所擁有的。基本上我需要鎖定方法來獲取鎖定,如果獲得鎖定則返回true,否則返回false。嘗試釋放鎖的解鎖方法,如果成功則返回true,否則返回false。這是一個自定義鎖定機制的好實現嗎?

這是一個正確的方式來實現這一點,或者可以做其他方式嗎?這些代碼可以添加哪些改進,或者可以通過哪些方式進行修改?

由於提前,

安德烈

private Long threadId; 

private int lockHolds; 

public synchronized boolean lock(long waitTime) throws DataStoreException { 
    if (lockHolds == 0) { 
     doLock(waitTime); 
     return true; 
    } 

    return false; 
} 

private synchronized void doLock(long waitTime) throws DataStoreException { 
    if (lockHolds == 0) { 
     lockHolds++; 
     this.threadId = Thread.currentThread().getId(); 
    } else if (lockHolds > 0 && this.threadId == Thread.currentThread().getId()) { 
     lockHolds++; 
    } else { 
     try { 
      wait(waitTime); 
      lockHolds++; 
      this.threadId = Thread.currentThread().getId(); 
     } catch (InterruptedException ie) { 
      ie.printStackTrace(); 
     } 
    } 

} 

public synchronized boolean unlock() { 
    if (lockHolds == 0) { 
     return false; 
    } 

    lockHolds--; 

    if (lockHolds == 0) { 
     notify(); 
     return true; 
    } 

    return false; 
} 
+1

使用'synchronized'來實現_implement_鎖定是一種自我挫敗,不是嗎? –

+0

工作代碼的評論比Codeoverview(codereview.stackexchange.com)更適合於比Stackoverflow。 –

+0

爲什麼不使用ReentrantLock作爲您想要測試的鎖並刪除synchronized關鍵字。 – Slimu

回答

4
  1. 這是錯誤的:

    wait(waitTime); 
    lockHolds++; 
    this.threadId = Thread.currentThread().getId(); 
    

你等着吧,然後從當前偷鎖擁有線程。該線程可能處於其關鍵部分的中間,因此您允許同時訪問關鍵部分。

  1. wait必須始終在一個循環中使用,該循環會重複測試正在等待的狀態,以防止虛假喚醒。

  2. lock()方法只檢查lockHolds變量,如果它不爲零則拒絕繼續,從而阻止鎖的重入行爲。

  3. 您的unlock方法是錯誤的,因爲任何線程都可以調用它並釋放另一個線程的鎖。

雖然我不熟悉你的要求,對我來說將是非常奇怪的要求定製的鎖實現,但允許它依靠兩個暗鎖執行和內置WAIT - 通知機制。但這一部分取決於你。

相關問題