1. 程式人生 > >Synchronized和Lock的用法和區別

Synchronized和Lock的用法和區別

1、Synchronized和Lock的用法和區別

1.synchronized是託管給JVM執行的,而Lock是Java寫的控制鎖的程式碼。 
2.synchronized原始採用的是CPU悲觀鎖機制,即執行緒獲得的是獨佔鎖。獨佔鎖意味著其他執行緒只能依靠阻塞來等待執行緒釋放鎖。而在CPU轉換執行緒阻塞時會引起執行緒上下文切換,當有很多執行緒競爭鎖的時候,會引起CPU頻繁的上下文切換導致效率很低。  
3.Lock用的是樂觀鎖方式。每次不加鎖而是假設沒有衝突而去完成某項操作,如果因為衝突失敗就重試,直到成功為止。 
4.ReentrantLock必須在finally中釋放鎖,否則後果很嚴重,編碼角度來說使用synchronized更加簡單,不容易遺漏或者出錯。 
5.ReentrantLock提供了可輪詢的鎖請求,他可以嘗試的去取得鎖,如果取得成功則繼續處理,取得不成功,可以等下次執行的時候處理,所以不容易產生死鎖,而synchronized則一旦進入鎖請求要麼成功,要麼一直阻塞,所以更容易產生死鎖。 
6.synchronized的話,鎖的範圍是整個方法或synchronized塊部分;而Lock因為是方法呼叫,可以跨方法,靈活性更大。

 

2、Synchronized和Lock的用法和區別

synchronized 是Java的關鍵字,是Java的內建特性,在JVM層面實現了對臨界資源的同步互斥訪問,但 synchronized 粒度有些大,在處理實際問題時存在諸多侷限性,比如響應中斷等。Lock 提供了比 synchronized更廣泛的鎖操作,它能以更優雅的方式處理執行緒同步問題。    

在效能上來說,如果競爭資源不激烈,兩者的效能是差不多的,而當競爭資源非常激烈時(即有大量執行緒同時競爭),此時Lock的效能要遠遠優於synchronized。所以說,在具體使用時要根據適當情況選擇。

效能比較:

    在JDK1.5中,synchronized是效能低效的。因為這是一個重量級操作,它對效能最大的影響是阻塞的是實現,掛起執行緒和恢復執行緒的操作都需要轉入核心態中完成,這些操作給系統的併發性帶來了很大的壓力。相比之下使用Java提供的Lock物件,效能更高一些。Brian Goetz對這兩種鎖在JDK1.5、單核處理器及雙Xeon處理器環境下做了一組吞吐量對比的實驗,發現多執行緒環境下,synchronized的吞吐量下降的非常嚴重,而ReentrankLock則能基本保持在同一個比較穩定的水平上。但與其說ReetrantLock效能好,倒不如說synchronized還有非常大的優化餘地,於是到了JDK1.6,發生了變化,對synchronize加入了很多優化措施,有自適應自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導致在JDK1.6上synchronize的效能並不比Lock差。官方也表示,他們也更支援synchronize,在未來的版本中還有優化餘地,所以還是提倡在synchronized能實現需求的情況下,優先考慮使用synchronized來進行同步。
當需要以下高階特性時,才應該使用Lock:可定時的、可輪詢的與可中斷的鎖獲取操作,公平佇列,或者非塊結構的鎖。否則,請使用synchronized。
 

3、Synchronized和Lock的用法和區別

那麼lock和synchronized的區別對比如下:
1)synchronized 在成功完成功能或者丟擲異常時,虛擬機器會自動釋放執行緒佔有的鎖;而Lock物件在發生異常時,如果沒有主動呼叫unLock()方法去釋放鎖,則鎖物件會一直持有,因此使用Lock時需要在finally塊中釋放鎖;
2)lock介面鎖可以通過多種方法來嘗試獲取鎖包括立即返回是否成功的tryLock(),以及一直嘗試獲取的lock()方法和嘗試等待指定時間長度獲取的方法,相對靈活了許多比synchronized;
3) 通過在讀多,寫少的高併發情況下,我們用ReentrantReadWriteLock分別獲取讀鎖和寫鎖來提高系統的效能,因為讀鎖是共享鎖,即可以同時有多個執行緒讀取共享資源,而寫鎖則保證了對共享資源的修改只能是單執行緒的。