淺談Java中Lock和Synchronized的區(qū)別
1. 從功能角度來(lái)看
Lock
和Synchronized
都是java中去用來(lái)解決線程安全問(wèn)題的一個(gè)工具
2. 從特性來(lái)看
Synchronized
是java中的同步關(guān)鍵字,Lock是J.U.C
包中提供的接口,而這個(gè)接口有很多的實(shí)現(xiàn)類(lèi),包括ReentrantLock
這樣重入鎖的實(shí)現(xiàn),Synchronized
可以通過(guò)兩種方式去控制鎖的力度
一種把synchronized
關(guān)鍵字修飾在方法層面,另一種是修飾在代碼塊上,可以通過(guò)synchronized
加鎖對(duì)象的生命周期,來(lái)控制鎖的作用范圍,鎖對(duì)象是靜態(tài)對(duì)象或者是類(lèi)對(duì)象,那么這個(gè)鎖就是屬于全局鎖,如果鎖對(duì)象是普通實(shí)例對(duì)象,那么這個(gè)鎖的范圍取決于這個(gè)實(shí)例的生命周期,Lock中鎖的粒度是通過(guò)它里面提供的lock()
方法和unlock()
方法來(lái)決定的
如上圖:在lock()方法和unlock()
方法之間的代碼,是能夠保證線程安全的,而鎖的作用域 取決于Lock實(shí)例的生命周期。Lock比Synchronized
的靈活性更高,Lock可以自主的去決定什么時(shí)候加鎖,什么時(shí)候釋放鎖,只需要調(diào)用lock()
和unlock
這兩個(gè)方法就可以了,Lock還提供了非阻塞的競(jìng)爭(zhēng)鎖的方法,叫tryLock()
,這個(gè)方法可以通過(guò)返回true/false
來(lái)告訴當(dāng)前線程是否已經(jīng)有其他線程正在使用鎖,而Synchronized由于是關(guān)鍵字,所以它無(wú)法去實(shí)現(xiàn)非阻塞競(jìng)爭(zhēng)鎖的方法,Synchroized
鎖的釋放是被動(dòng)的,當(dāng)Synchronized
同步代碼塊,執(zhí)行結(jié)束以后,或者代碼出現(xiàn)異常的時(shí)候才會(huì)被釋放,Lock提供了公平鎖和非公平鎖的機(jī)制,公平鎖是指線程競(jìng)爭(zhēng)鎖資源的時(shí)候,已經(jīng)有其它線程正在排隊(duì),或者等待鎖釋放,那么當(dāng)前競(jìng)爭(zhēng)鎖的線程,是無(wú)法去插隊(duì)的,非公平鎖就是不管是否有線程在排隊(duì)等待鎖,它都會(huì)去嘗試去競(jìng)爭(zhēng)一次鎖,Synchronized
只提供方了一種非公平鎖的實(shí)現(xiàn)。
3. 從性能方面來(lái)看
Synchronized
和lock在性能方面相差不大,在實(shí)現(xiàn)上會(huì)有一定的區(qū)別,Synchronized
引入了偏向鎖,輕量級(jí)鎖,重量級(jí)鎖以及鎖升級(jí)的機(jī)制來(lái)實(shí)現(xiàn)鎖的優(yōu)化,而Lock中則用到了自旋鎖的方式去實(shí)現(xiàn)性能優(yōu)化
到此這篇關(guān)于淺談Java中Lock
和Synchronized
的區(qū)別的文章就介紹到這了,更多相關(guān)Lock
和Synchronized
的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java靜態(tài)和非靜態(tài)成員變量初始化過(guò)程解析
這篇文章主要介紹了Java靜態(tài)和非靜態(tài)成員變量初始化過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01SpringBoot+Vue靜態(tài)資源刷新后無(wú)法訪問(wèn)的問(wèn)題解決方案
這篇文章主要介紹了SpringBoot+Vue靜態(tài)資源刷新后無(wú)法訪問(wèn)的問(wèn)題解決方案,文中通過(guò)代碼示例和圖文講解的非常詳細(xì),對(duì)大家解決問(wèn)題有一定的幫助,需要的朋友可以參考下2024-05-05Java獲取Class對(duì)象的幾種方式小結(jié)
本文給大家分享了Java獲取Class對(duì)象的幾種方式,使用類(lèi)名.class 語(yǔ)法,使用對(duì)象的 getClass()方法,使用 Class.forName()方法等多種方法,不同的方式適用于不同的場(chǎng)景,需要的朋友可以參考下2023-10-10淺談java.util.concurrent包中的線程池和消息隊(duì)列
這篇文章主要介紹了淺談java.util.concurrent包中的線程池和消息隊(duì)列,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08SpringBoot開(kāi)發(fā)技巧啟動(dòng)時(shí)配置校驗(yàn)實(shí)現(xiàn)示例
這篇文章主要為大家介紹了SpringBoot開(kāi)發(fā)在啟動(dòng)時(shí)自動(dòng)配置校驗(yàn)的實(shí)現(xiàn)示例及原理解析,有需要的朋友可以借鑒參考下希望能夠有所幫助2021-10-10Spring?Boot集成Milvus快速入門(mén)demo示例詳解
Milvus是一種高性能向量數(shù)據(jù)庫(kù),支持從筆記本到大型分布式系統(tǒng)的多環(huán)境運(yùn)行,它以開(kāi)源和云服務(wù)形式提供,是LFAI & Data Foundation的項(xiàng)目,采用Apache 2.0許可,Milvus特別支持高并行化和解耦的系統(tǒng)架構(gòu),使其能夠隨數(shù)據(jù)增長(zhǎng)而擴(kuò)展,支持各種復(fù)雜搜索功能,滿(mǎn)足企業(yè)級(jí)AI應(yīng)用需求2024-09-09