簡體   English   中英

Java中是否存在一種快速失敗的同步方式?

[英]Is there a fail-fast way of synchronization in Java?

假設我有一個這樣的代碼片段

synchronized(obj) {
    do something;
}

如果obj已被某個其他線程鎖定,則此代碼將等待直到obj釋放,之后它將嘗試獲取鎖定。

但我想知道如果無法立即獲得鎖定,是否有任何方法可以跳過代碼塊?

換句話說,有沒有辦法檢測對象是否已被鎖定?

更新:

感謝您提及Lock接口,但這需要程序遵守相同的合同,即它們都引用Lock對象而不是synchronized關鍵字。

我想知道是否有內置的檢查鎖定狀態的方法?

謝謝。

Java中是否存在一種快速失敗的同步方式?

我認為使用“快速失敗”來描述你在這里嘗試做什么是一個糟糕的術語選擇。 快速失敗意味着不立即獲取鎖定是失敗或應用程序錯誤; cf失敗的快速迭代器拋出未經檢查的CCME。 這不是鎖通常提供的語義模型,特別是這里。 一個更好的術語是“非阻塞”

此外,目前尚不清楚的是默默跳過一個代碼塊,因為你不能獲得一個鎖是有用的行為。 在大多數情況下,應用程序需要知道已經采用了“跳過”路徑。

拋開這些點,你不能使用原始對象鎖。

(好吧,在某些JVM上,您可以使用sun.misc.Unsafe來執行此操作,但這是一個非常糟糕的主意。您可能會發現您的編譯器,類加載器或安全沙箱阻止您使用Unsafe API。 ..它應該。此外,這個API不被稱為“不安全”!)

java.util.concurrent.locks.Lock API有一個方法,允許您嘗試獲取鎖定而不會阻塞。 具體來說, tryLock()方法嘗試獲取鎖定,並在鎖定正在使用時立即返回false

還有其他更高級別的並發類可以用作ersatz鎖; 例如Semaphore


換句話說,有沒有辦法檢測對象是否已被鎖定?

實際上,這有點不同......也不完全有用。 當然,你可以(假設)測試是否持有鎖。 (事實上​​,一些Lock類明確支持這一點。)但這並不意味着你可以保證能夠在不阻塞的情況下獲得鎖定。 如果你做出(不正確的)假設,你已經在你的代碼中引入了一個Heisenbug。


我想知道是否有內置的檢查鎖定狀態的方法?

[假設你指的是原始鎖...]

不,沒有。 至少,不在運行的應用程序本身內。 (調試代理可以執行此操作,但應用程序與其JVM的調試代理進行通信是不切實際的。)

如果你想/需要做這種事情,你就沒有真正的選擇 ,不涉及改變你的應用程序的鎖定機制。 它就是這樣兒的。

你可以使用java.util.concurrent.Semaphore來實現它,它將允許你更多的控制

暫無
暫無

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

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