Java中synchronized與lock的區別與使用場景
synchronized與object物件本身監視器方法notify、wait、notifyAll實現執行緒等待和通知,Lock與condition搭配實現執行緒等待/通知。一個物件可以有多個condition,執行緒可以註冊到不同的condition,synchronized相當於一個物件只有一個單一的condition,所有執行緒只能註冊它身上。
lock的鎖是是一個介面,而synchronized是在JVM層面實現的。synchronized釋放鎖有兩種方式:第一種,以獲取鎖的執行緒執行完同步程式碼,釋放鎖 。第二種,執行緒執行發生異常,jvm會讓執行緒釋放鎖。lock鎖的釋放:出現異常時必須在finally中釋放鎖,不然容易造成執行緒死鎖。
lock顯示獲取鎖和釋放鎖,提供超時獲取鎖、可中斷地獲取鎖。synchronized是以隱式地獲取和釋放鎖,synchronized無法中斷一個正在等待獲取鎖的執行緒。
https://blog.csdn.net/qq_40068214/article/details/88983183
總之,如果這個獲取鎖的執行緒由於要等待IO或者其他原因(比如呼叫sleep方法)被阻塞了,但是又沒有釋放鎖,其他執行緒便只能乾巴巴地等待,試想一下,這多麼影響程式執行效率。因此就需要有一種機制可以不讓等待的執行緒一直無期限地等待下去(比如只等待一定的時間或者能夠響應中斷),通過Lock就可以辦到。
再舉一個例子:當有多個執行緒讀寫檔案時,讀操作和寫操作會發生衝突現象,寫操作和寫操作會發生衝突現象,但是讀操作和讀操作不會發生衝突現象。但是採用synchronized關鍵字來實現同步的話,就會導致一個問題:如果多個執行緒都只是進行讀操作,當一個執行緒在進行讀操作時,其他執行緒只能等待無法進行讀操作。因此就需要一種機制來使得多個執行緒都只是進行讀操作時,執行緒之間不會發生衝突,通過Lock就可以辦到。另外,通過Lock可以知道執行緒有沒有成功獲取到鎖。這個是synchronized無法辦到的。總的來說,也就是說Lock提供了比synchronized更多的功能。
Lock和synchronized的選擇
1)Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現;
2)synchronized在發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;
3)Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;
4)通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。
5)Lock可以提高多個執行緒進行讀操作的效率。
在效能上來說,如果競爭資源不激烈,兩者的效能是差不多的,而當競爭資源非常激烈時(即有大量執行緒同時競爭),此時Lock的效能要遠遠優於synchronized。所以說,在具體使用時要根據適當情