簡體   English   中英

創建“Lock”類(擴展Object並且什么也不做)有什么好處?

[英]What's the benefit of creating a “Lock” class (which extends Object and does nothing)?

大家好,每當我使用synchronized語句時,我經常使用這種模式:

private static Object lock = new Object();

public void F(){
    //..
    synchronized (lock){
        //..
    }
    //..
}

但是,在java.lang.Reference的源代碼中,我看到他們使用這種模式:

static private class Lock { };
private static Lock lock = new Lock();

public void run() {
//..
synchronized(lock){
    //..
}
//..
}

我想知道聲明一個新類Lock的好處是什么(它基本上擴展了Object並且什么都不做)?

或者更確切地說,為什么他們不使用private static Lock lock = new Object();

以下代碼:

synchronized(lock){
}

實際上並沒有使用Lock機制,您只是使用Object上的內置同步功能。 在這種情況下,您也可以使用普通的舊Object 擴展Object的鎖對象的好處是它在具有類名的調試工具中顯示而不僅僅是一個普通的Object ,這在追捕死鎖時更有用。

請參閱此處了解Lock API。

Lock的好處是可以獲得更多功能,例如能夠“嘗試”鎖定,然后在失敗時繼續執行代碼。 此外,它具有與同步塊不同的屬性,因為它不可重入(線程不能在同一個鎖上保存多個鎖,然后釋放它們)。 如果你想要這樣的東西,你可以使用ReentrantLock

您還有一些冷卻器鎖,例如ReentrantReadWriteLock ,它支持多個讀卡器,但只要ReentrantReadWriteLock器鎖定它,就不允許讀取器。 對於不同類型的應用程序,有一個很大的鎖定生態系統。

我想知道聲明一個新類Lock的好處是什么(它基本上擴展了Object並且什么都不做)?

可讀性。 我相信創建一個Object的實例至少是奇怪的,所以為此目的而擁有一個單獨的,命名良好的類似乎是個好主意。

包含鎖的BTW字段應該始終是final ,否則您會遇到麻煩。

鎖對象類的名稱出現在線程轉儲中。 這樣可以更輕松地解釋此類轉儲。

例如, 是一個使用Reference.Lock的示例。 您可以立即看到它是什么類型的鎖,而不是將它與ReferenceQueue的鎖混淆。 這在Sun JRE的早期版本中更為重要,其中未顯示對象標識哈希。

"Reference Handler" daemon prio=10 tid=0x000000000068f400 nid=0xbf5 in Object.wait() [0x000000004055d000..0x000000004055dca0]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00007f651aa10338> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0x00007f651aa10338> (a java.lang.ref.Reference$Lock)

至於

private static Lock lock = new Object();

不編譯(應該使用final !)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM