隱式鎖Synchronized與顯示鎖Lock的用法和簡單對比(轉(zhuǎn))

出自:https://blog.csdn.net/u011519624/article/details/61628611

synchronized妓忍、lock虏两,都可以稱呼為:對象鎖、對象監(jiān)視器世剖、同步監(jiān)視器定罢。

它們的作用應(yīng)該是相同的,差別未知旁瘫。

鎖是為多線程服務(wù)的祖凫,目的是實現(xiàn)多線程環(huán)境下同步排隊訪問某些指定代碼,最終目的是多線程下的數(shù)據(jù)安全酬凳。它們在單線程環(huán)境下沒有意義

一惠况、Synchronized

Synchronized是Java的關(guān)鍵字,當(dāng)它用來修飾一個方法或一個代碼塊時宁仔,能夠保證在同一時刻最多只有一個線程執(zhí)行該代碼稠屠。因為當(dāng)調(diào)用Synchronized修飾的代碼時,并不需要顯示的加鎖和解鎖的過程翎苫,所以稱之為隱式鎖权埠。

Sychronized的用法:

1、同步方法體煎谍,在方法聲明中使用攘蔽,如下:

public synchronized void method(){

? ? ? ? //方法體

}

2、同步代碼塊呐粘,修飾在代碼塊外層秩彤,指定加鎖對象,如下:

public void method2(){

? ? synchronized (this) {

? ? //一次只能有一個線程進入?

? ? }

}

上述synchronized(this)指定了當(dāng)前對象本身作為鎖事哭,和它持有相同對象鎖的地方將產(chǎn)生互斥性。當(dāng)一個線程訪問method2的同步代碼塊時瓜富,它就獲得了這個object的對象鎖鳍咱。其他的線程對該object所有同步代碼部分的訪問都被暫時的阻塞。

sychronized的不同寫法對程序響應(yīng)的快慢和對資源高并發(fā)的利用程度不一樣与柑,性能和執(zhí)行效率從差到優(yōu)排序如下:

差? ? ? ? ? ? ? ? ? ? ?較差? ? ? ? ? ? ? ? ? ?優(yōu)

同步方法體 < 同步代碼塊 < 小對象鎖同步代碼塊

小對象鎖同步代碼塊指鎖的對象的所占內(nèi)存小谤辜,因為鎖是對象蓄坏,加鎖和解鎖都需要釋放資源,那肯定是鎖對象越小越好丑念,實際應(yīng)用如下:

private byte[] lock = new byte[1];

public void method3(){

? ? synchronized (lock) {

? ? ? ? //一次只能有一個線程進入?

? ? }

}

二涡戳、Lock

Lock是一個接口,提供了無條件的脯倚、可輪詢的渔彰、定時的、可中斷的鎖獲取操作推正,所有的加鎖和解鎖操作方法都是顯示的恍涂,因而稱為顯示鎖。

下面針對Lock的幾個實現(xiàn)類ReentrantLock植榕、ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock解析再沧。

ReentrantLock(可重入鎖),是一個互斥的同步器尊残,用ReentrantLock實現(xiàn)同步機制比sychronized實現(xiàn)更具伸縮性炒瘸。使用如下:

private final ReentrantLock lock = new ReentrantLock();

? ? public void m(){

? ? ? ? lock.lock();//獲得鎖

? ? ? ? try{

? ? ? ? ? ? //方法體

? ? ? ? }finally{

? ? ? ? ? ? lock.unlock();//務(wù)必釋放鎖

? ? ? ? }

? ? }

注意:在使用ReentrantLock時,一定要有釋放鎖的操作寝衫。

三顷扩、ReadWriteLock(讀寫鎖)

是一個接口,提供了readLock和writeLock兩種鎖的操作竞端,也就是說一個資源能夠被多個讀線程訪問屎即,或者被一個寫線程訪問,但是不能同時存在讀寫線程事富。

(非原文:大概是讀鎖可以多線程異步訪問技俐。但是寫鎖必須同步。讀寫鎖也必須同步排隊訪問)

也就是說讀寫鎖應(yīng)用的場景是一個資源被大量讀取操作统台,而只有少量的寫操作雕擂。我們先看其源碼:

public interface ReadWriteLock {

? ? Lock readLock();

? ? Lock writeLock();

}

從源碼看出,ReadWriteLock借助Lock來實現(xiàn)讀寫兩個鎖并存贱勃、互斥的機制井赌。每次讀取共享數(shù)據(jù)就需要讀取鎖,需要修改共享數(shù)據(jù)就需要寫入鎖贵扰。

讀寫鎖的機制:

1仇穗、讀-讀不互斥,讀線程可以并發(fā)執(zhí)行戚绕;

2纹坐、讀-寫互斥,有寫線程時舞丛,讀線程會堵塞耘子;

3果漾、寫-寫互斥,寫線程都是互斥的谷誓。

使用方法:

//創(chuàng)建ReentrantReadWriteLock對象

private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

? ? //抽取讀寫鎖

? ? private Lock readLock = rwl.readLock();

? ? private Lock writeLock = rwl.writeLock();

? ? public int getXXX(){

? ? ? ? readLock.lock();

? ? ? ? try{

? ? ? ? ? ? //執(zhí)行操作

? ? ? ? }finally{

? ? ? ? ? ? readLock.unlock();

? ? ? ? }

? ? }

? ? public void setXXX(){

? ? ? ? writeLock.lock();

? ? ? ? try{

? ? ? ? ? ? //執(zhí)行操作

? ? ? ? }finally{

? ? ? ? ? ? writeLock.unlock();

? ? ? ? }

? ? }

ReentrantReadWriteLock和ReentrantLock的比較:

ReentrantReadWriteLock是對ReentrantLock的復(fù)雜擴展绒障,能適合更加復(fù)雜的業(yè)務(wù)場景,ReentrantReadWriteLock可以實現(xiàn)一個方法中讀寫分離的鎖的機制捍歪。而ReentrantLock只是加鎖解鎖一種機制户辱。

最后對比Synchronized、ReentrantLock和ReentrantReadWriteLock:

Synchronized是在JVM層面上實現(xiàn)的费封,無需顯示的加解鎖焕妙,而ReentrantLock和ReentrantReadWriteLock需顯示的加解鎖,一定要保證鎖資源被釋放弓摘;

Synchronized是針對一個對象的焚鹊,而ReentrantLock和ReentrantReadWriteLock是代碼塊層面的鎖定;

ReentrantReadWriteLock引入了讀寫和并發(fā)機制韧献,可以實現(xiàn)更復(fù)雜的鎖機制末患,并發(fā)性相對于ReentrantLock和Synchronized更高。

非原文:疑問

1锤窑、synchronized網(wǎng)上有多種稱呼:對象鎖璧针、對象監(jiān)視器、同步監(jiān)視器渊啰。能理解怎么用就行探橱。

無論怎么稱呼,它都是為多線程服務(wù)的绘证,目的是實現(xiàn)多線程環(huán)境下同步訪問某些方法晨缴,最終目的是多線程下數(shù)據(jù)安全寓涨。單線程下沒有意義

synchronized監(jiān)視的是整個對象铆帽,所以(Java設(shè)計規(guī)定)當(dāng)一個線程正在訪問同步方法压真、或同步代碼塊時,

其他線程不能進入該對象的任意一個同步方法魏宽、或者同步代碼塊腐泻。

(非同步方法、非同步代碼塊队询,沒有限制)

那么ReentrantLock也是這么設(shè)計的嗎派桩?

代碼測試結(jié)果:

(1)、當(dāng)lock實例化為一個成員字段時蚌斩,監(jiān)視的也是一個對象(當(dāng)前所在類的當(dāng)前對象)

和synchronized沒有差別铆惑。

(2)、如果lock實例化為局部變量,多線程訪問該方法時鸭津,不能同步訪問了

lock使用方式之一:lock對象只能作為成員字段使用。

synchronized代碼塊肠缨,分析多線程環(huán)境下怎么執(zhí)行時逆趋,可以看作是獨立的一個同步方法

2、synchronized晒奕、ReentrantLock都是重入鎖

重入鎖大概意思舉例:

public synchronized void get1(

System.out.print(1); // start

get2();? // 嵌套訪問另一個同步方法get2()

System.out.print(2); // end

){}

public synchronized void get2(){}

一個線程訪問get1()時闻书,代碼由上而下順序執(zhí)行,start? ? get2()? ? ?end,

可重入脑慧,可以理解為兩個方法魄眉,兩把鎖,先進入get1()的鎖闷袒,再進入 get2()的鎖坑律,最后重新進入? get1()的鎖。

Java這樣設(shè)計囊骤,同步方法嵌套訪問不會發(fā)生死鎖晃择?重入的概念用來理解這種設(shè)計,知道怎么用就行

3也物、public static synchronized void get3(){}

這個同步方法宫屠,監(jiān)視的是該類的class對象。例如:Test.class

那么滑蚯,監(jiān)視對象浪蹂、監(jiān)視class對象,怎么表達(dá)告材。坤次。。應(yīng)該是兩種不相干的監(jiān)視行為创葡。

代碼測試結(jié)果:是兩種不相干的監(jiān)視行為浙踢。(對象、class對象灿渴,不是同一個對象)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洛波,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子骚露,更是在濱河造成了極大的恐慌蹬挤,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棘幸,死亡現(xiàn)場離奇詭異焰扳,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門吨悍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扫茅,“玉大人,你說我怎么就攤上這事育瓜『叮” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵躏仇,是天一觀的道長恋脚。 經(jīng)常有香客問我,道長焰手,這世上最難降的妖魔是什么糟描? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮书妻,結(jié)果婚禮上船响,老公的妹妹穿的比我還像新娘。我一直安慰自己驻子,他們只是感情好灿意,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著崇呵,像睡著了一般缤剧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上域慷,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天荒辕,我揣著相機與錄音,去河邊找鬼犹褒。 笑死抵窒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叠骑。 我是一名探鬼主播李皇,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宙枷!你這毒婦竟也來了掉房?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤慰丛,失蹤者是張志新(化名)和其女友劉穎卓囚,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诅病,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡哪亿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年粥烁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝇棉。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡讨阻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篡殷,到底是詐尸還是另有隱情变勇,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布贴唇,位于F島的核電站,受9級特大地震影響飞袋,放射性物質(zhì)發(fā)生泄漏戳气。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一巧鸭、第九天 我趴在偏房一處隱蔽的房頂上張望瓶您。 院中可真熱鬧,春花似錦纲仍、人聲如沸呀袱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夜赵。三九已至,卻和暖如春乡革,著一層夾襖步出監(jiān)牢的瞬間寇僧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工沸版, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘁傀,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓视粮,卻偏偏與公主長得像细办,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蕾殴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354