關(guān)于synchronized、volatile、ReentrantLock的區(qū)別與對(duì)比
聊之前先說一下并發(fā)編程的3個(gè)特性。
并發(fā)編程特性
- 原子性:對(duì)共享資源的一組操作,要么成功要么失敗,不會(huì)出現(xiàn)部分成功部分失敗的情況。
- 可見性: 當(dāng)線程獲取到瑣時(shí),會(huì)拷貝一份共享資源到本地內(nèi)存,釋放鎖時(shí)會(huì)將共享資源刷新到主內(nèi)存中??梢娦允侵府?dāng)共享資源發(fā)生變化時(shí),其他線程都能夠看到這個(gè)變化。
- 有序性:為了提高效率,編譯器和處理器會(huì)對(duì)代碼進(jìn)行指令重排,單線程的情況下,指令重拍不會(huì)受到影響,多線程情況下可能會(huì)影響代碼執(zhí)行的正確性。有序性是指代碼編寫順序和執(zhí)行順序是一致的。
volatile
volatile 是JVM提供的最輕量級(jí)的同步機(jī)制,編譯器不會(huì)對(duì)其進(jìn)行優(yōu)化。
特性:
- volatile 只保證共享資源的可見性和有序性。
- 使用volatile修飾共享資源時(shí),如果共享資源變化時(shí),會(huì)直接將緩存中的數(shù)據(jù)寫回到主內(nèi)存中去,數(shù)據(jù)也是從主內(nèi)存中讀取,從而保證了可見性。
- volatile 底層是通過操作系統(tǒng)的內(nèi)存屏障來實(shí)現(xiàn)的,由于使?了內(nèi)存屏障,所以會(huì)禁?指令重排,從而就保證了有序性。
作用的地方:
volatile 只能用來修飾成員變量。
public class VolatileTest {
private volatile static String staticVolatile;
private volatile String memberVolatile;
}
synchronized
synchronized關(guān)鍵字是java提供的內(nèi)置鎖來保證我們對(duì)共享資源的同步,它會(huì)自動(dòng)加鎖和釋放鎖,它的鎖是非公平鎖, synchronized關(guān)鍵字標(biāo)記的地方會(huì)被編譯器進(jìn)行優(yōu)化。synchronized會(huì)使線程串行執(zhí)行,可能會(huì)造成線程阻塞。
特性
- synchronized關(guān)鍵字使線程串行化執(zhí)行,所以保證了并發(fā)安全的3個(gè)特性,并且還擁有以下兩個(gè)特性:
- 互斥性:同時(shí)只有一個(gè)線程能夠訪問synchronized方法或者同步代碼塊。
- 可重入性:synchronized是可重入鎖,通俗解釋可重入鎖就是當(dāng)一個(gè)線程獲取到了某個(gè)對(duì)象鎖或者類鎖之后,這個(gè)線程在未釋放鎖之前,再調(diào)用該鎖的其他synchronized方法或代碼塊時(shí),不用再次重新獲得鎖。
作用的地方
synchronized關(guān)鍵字可用來修飾方法或者代碼塊。
修飾方法,分為實(shí)例方法和靜態(tài)方法
- 修飾實(shí)例方法,對(duì)象鎖
public synchronized void objectMethods(){
.....
}
- 修飾靜態(tài)方法,類鎖
public static synchronized void staticMethods(){
.....
}
修飾代碼塊
obj為對(duì)象的引用 對(duì)象鎖
public void objectMethods(){
synchronized (obj){
}
}
Object 為某個(gè)類 類鎖
public void classLock(){
synchronized (Object.class){
}
}
ReentrantLock
Lock 是 Java 5提供的一個(gè)具有鎖機(jī)制的接口,ReentrantLock 是Lock的一個(gè)實(shí)現(xiàn),內(nèi)部是通過AQS(AbstractQueuedSynchronizer)實(shí)現(xiàn)的。ReentrantLock翻譯過來是可重入鎖,它和synchronized類似,ReentrantLock 需要手動(dòng)加鎖和釋放鎖, 相對(duì)于synchronized它更加靈活,提供了更多的方法。 ReentrantLock 有公平鎖和非公平鎖兩種方式,默認(rèn)是使用公平鎖。
特性
ReentrantLock 是可重入的同步鎖,所以它除了具有并發(fā)編程的三大特性,還具有可重入性。
作用的地方
ReentrantLock 是一個(gè)類,它既可以作為成員變量,也可以作為局部變量使用。做為成員變量和局部變量時(shí),使用的方式有一點(diǎn)點(diǎn)不同,不管使用哪種方式,最后都別忘了要調(diào)用unlock() 方法手動(dòng)釋放鎖。
做為成員變量使用格式:
private Lock globalLock = new ReentrantLock();
public void globalLock(){
if (globalLock.tryLock()) {
try {
} catch (Exception e) {
}finally {
globalLock.unlock();
}
}
}
上面的tryLock() 方法是嘗試獲取鎖,如果獲取成功返回true,否則返回false,也可以換成加了等待時(shí)間的 boolean tryLock(long time, TimeUnit unit) 方法,在設(shè)定的等待時(shí)間內(nèi)獲取鎖成功則返回true,否則false。
做為局部變量使用格式:
public void lock(){
Lock lock = new ReentrantLock();
lock.lock();
try {
}finally {
lock.unlock();
}
}
對(duì)比
簡(jiǎn)單對(duì)比一下三者之間的區(qū)別:
| volatile | synchronized | ReentrantLock | |
| 是否是關(guān)鍵字 | 是 | 是 | 否 |
| 是否需要手動(dòng)加鎖/釋放鎖 | 否 | 否 | 是 |
| 是否能保證并發(fā)安全 | 否 | 是 | 是 |
| 是否是公平鎖 | \ | 否 | 有公平鎖和非公平鎖兩種實(shí)現(xiàn) |
| 是否會(huì)阻塞線程 | 否 | 是 | 是 |
| JVM是否會(huì)對(duì)其優(yōu)化 | 否 | 是 | 否 |
| 特性 | 可見性、有序性 | 可見性、有序性、原子性 | 可見性、有序性、原子性 |
| 使用的地方 | 成員變量 | 方法、代碼塊 | 成員變量、局部變量 |
到此這篇關(guān)于關(guān)于synchronized、volatile、ReentrantLock的區(qū)別與對(duì)比的文章就介紹到這了,更多相關(guān)synchronized、volatile、ReentrantLock的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java鎖機(jī)制synchronized與ReentrantLock全方面解析
- Java中synchronized和ReentrantLock的區(qū)別對(duì)比
- 深入理解Java中的synchronized 和 ReentrantLock 底層原理
- Java之synchronized(含與ReentrantLock的區(qū)別解讀)
- Java中的synchronized和ReentrantLock的區(qū)別詳細(xì)解讀
- Synchronized?和?ReentrantLock?的實(shí)現(xiàn)原理及區(qū)別
- Java常用鎖synchronized和ReentrantLock的區(qū)別
- Java線程安全解決方案(synchronized,ReentrantLock,Atomic)
- 深入理解java內(nèi)置鎖(synchronized)和顯式鎖(ReentrantLock)
- synchronized?vs?ReentrantLock性能對(duì)比:哪個(gè)更適合高并發(fā)場(chǎng)景?
相關(guān)文章
Java中Iterator與ListIterator迭代的區(qū)別
本文主要介紹了Java中Iterator與ListIterator迭代的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
springboot加載不到nacos配置中心的配置問題處理
這篇文章主要介紹了springboot加載不到nacos配置中心的配置問題處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-06-06
java中url漢字編碼互相轉(zhuǎn)換實(shí)例
這篇文章介紹了java中url漢字編碼互相轉(zhuǎn)換實(shí)例,有需要的朋友可以參考一下2013-10-10
解決Properties屬性文件中的值有等號(hào)和換行的小問題
這篇文章主要介紹了解決Properties屬性文件中的值有等號(hào)有換行的小問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
基于servlet實(shí)現(xiàn)統(tǒng)計(jì)網(wǎng)頁訪問次數(shù)
這篇文章主要為大家詳細(xì)介紹了基于servlet實(shí)現(xiàn)統(tǒng)計(jì)網(wǎng)頁訪問次數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
使用spring通過aop獲取方法參數(shù)和參數(shù)值
這篇文章主要介紹了使用spring通過aop獲取方法參數(shù)和參數(shù)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
spring定時(shí)器定時(shí)任務(wù)到時(shí)間未執(zhí)行問題的解決
這篇文章主要介紹了spring定時(shí)器定時(shí)任務(wù)到時(shí)間未執(zhí)行問題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java中Date與String相互轉(zhuǎn)換的方法
這篇文章主要為大家詳細(xì)介紹了Java中Date與String相互轉(zhuǎn)換方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10

