2017-08-09 30 views
-1

上明確持有鎖有被從多個線程訪問的對象。我想實現它,以便爲了訪問它的setter和getter,調用者必須先明確地鎖定它,然後在完成後解鎖它。儘管我使用synchronized方法,但與java的更多顯式鎖定API相比,它看起來並不直接。這是使用ReentrantLock的當前存根實現。因此,如果一個線程想要調用SetVal(int val),它將首先調用Lock(),然後在完成時調用Unlock()。我已經放置了isLocked()檢查其setter/getter方法來執行此規則。並且我在解鎖中添加了一個額外的鎖定呼叫,以確保只有擁有該鎖的線程才能繼續解鎖(ReentrackLock的一個獨特功能)。在調用Unlock()方法之前,可以多次調用該對象的setter/getters。所以在Unlock()方法中,我必須迭代其HoldCount併爲每個計數解鎖。我如何將Java對象

我不知道是否有實現這一目標的一個更有效和習慣的方法?

+2

嗯?只要使方法「同步」。根本不需要呼叫者的操作。沒有比這更直接的了。 – EJP

+0

每次方法調用後,我都不會丟失對象上的鎖嗎?我不想那樣。我想保證一個線程在一系列方法調用期間對對象有一個鎖。 –

+0

哦 - 確定它好像如果我只是做了同步的(數據)塊,並把該塊中的數據的方法的調用,會做的伎倆? –

回答

0

如果你只使用int值,然後可以去AtomicInteger

或使所有的方法進行同步要從比賽狀態,以防止。

,或者如果你想支持同步的和正常的,那麼你可以像坑一個collections.SynchronizedSet.Hope包裝,這將幫助。

0

您正在運行到與你的方法錯了方向。 OOP範例聲明所有數據都應該在內部進行保存和管理,但是您所做的是通過將內部數據提供給調用者來對其進行外部控制。

一個好的設計會試圖隱瞞事實,鎖定的甚至是必要的,做它的內部,以擺脫這種任務的調用者。特別是因爲如果您將正確鎖定的責任傳遞給調用者,那麼每個調用者都可能成爲潛在的線程問題。但是,如果你在內部鎖定,只有一個潛在的錯誤來源,所以如果你遇到了一個問題,你知道在哪裏看。

這是你會怎麼做正確有關OOP範式:

public class Data { 
    // protected so it is accessible to derived classes 
    // final so the lock object cannot be (accidentally) reassigned 
    // Lock (base class) so it is easier to change the implementation later 
    protected final Lock lock; 

    // clear naming 
    private int value; 

    public Data() { 
     // value is automatically initialized with 0 
     this.lock = new ReentrantLock(); 
    } 

    // by convention the setter for ... is set... 
    public void setValue(final int value) { 
     this.lock.lock(); 
     // absolutely use try/finally here, to ensure it is unlocked in all cases 
     try { 
      this.value = value; 
     } finally { 
      this.lock.unlock(); 
     } 
    } 

    // by convention the getter for ... is get... 
    public int getValue() { 
     this.lock.lock(); 
     try { 
      return this.value; 
     } finally { 
      this.lock.unlock(); 
     } 
    } 
}