🎈專欄鏈接:多線程相關(guān)知識詳解
創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站制作、成都網(wǎng)站建設(shè)、新城網(wǎng)絡(luò)推廣、小程序制作、新城網(wǎng)絡(luò)營銷、新城企業(yè)策劃、新城品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供新城建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com目錄
1.樂觀鎖VS悲觀鎖
2.讀寫鎖VS普通互斥鎖
3.輕量級鎖VS重量級鎖
4.自旋鎖VS掛起等待鎖?
5. 公平鎖VS非公平鎖
6.可重入鎖VS不可重入鎖
7.關(guān)于synchronized的鎖策略以及自適應(yīng)
樂觀鎖:預(yù)測鎖沖突的概率不高,因此做的工作就可以簡單點
悲觀鎖:預(yù)測鎖沖突的概率較高,因此做的工作就要復(fù)雜一些
鎖沖突就是多個線程競爭同一把鎖,會產(chǎn)生阻塞等待
舉個例子:
樂觀鎖:A在學(xué)校的教室內(nèi)卷的時候,就比較樂觀,就覺得在教室學(xué)習(xí)的時候,不怕被B發(fā)現(xiàn)自己在偷偷內(nèi)卷,而且B來教室內(nèi)卷的概率比較少,就不關(guān)教室門,即使B進來發(fā)現(xiàn)A自己在內(nèi)卷,也不影響A自己學(xué)習(xí)
悲觀鎖:B在教室內(nèi)卷的時候,就比較悲觀,覺得A天天想要學(xué)習(xí),來教室內(nèi)卷,怕A的成績超過B自己,就每次都關(guān)教室門,即使A不來教室學(xué)習(xí),也把門給關(guān)上,多做了一步鎖門操作
這兩種鎖是站在加鎖解鎖的角度看待的,看的是加鎖解鎖的過程中所干的活是多還是少
2.讀寫鎖VS普通互斥鎖讀寫鎖:
Ⅰ:加讀鎖
? Ⅱ:加寫鎖
讀鎖和讀鎖之間不會產(chǎn)生競爭
寫鎖和寫鎖之間會產(chǎn)生競爭
讀鎖和寫鎖會產(chǎn)生競爭
普通互斥鎖:就如同Synchronized,當(dāng)兩個線程競爭同一把鎖的時候就會產(chǎn)生阻塞等待
多個線程同時讀一個變量并沒有問題,而且讀的場景相比于寫的場景就多了很多,使用讀寫鎖相比于普通互斥鎖就減少了很多的鎖競爭,大大的優(yōu)化了效率
3.輕量級鎖VS重量級鎖輕量級鎖的加鎖解鎖開銷比較少,典型的是純用戶態(tài)的加鎖解鎖邏輯,開銷是比較少的
重量級鎖的加鎖解鎖開銷比較大,典型的是進入了系統(tǒng)內(nèi)核態(tài)的加鎖解鎖邏輯,開銷是比較大的
4.自旋鎖VS掛起等待鎖?這兩種鎖是站在結(jié)果的角度看待最終加鎖解鎖消耗的時間是多還是少,和樂觀鎖與悲觀鎖并不一樣
通常情況下樂觀鎖比較輕量,悲觀鎖比較重量,但是也并不絕對
自旋鎖:相當(dāng)于是"忙等"的狀態(tài),大量消耗的CPU資源,反復(fù)詢問當(dāng)前鎖是否就緒
掛起等待鎖:先把CPU資源空閑出來去做其他的事情,過一段時間才詢問當(dāng)前鎖是否就緒
舉個例子:
在我們等人的時候,對方還沒有到約定地點,一直反復(fù)的打電話催促就是自旋鎖,而當(dāng)你發(fā)現(xiàn)對方還沒到的時候,就在約定的地點找個地方玩手機,叫他來了再在約定的地點旁邊找我們一下,多消耗一點時間,卻能夠用這些時間去做其他的事情,時間被利用起來了,這就是掛起等待鎖
自旋鎖是輕量級鎖的一種體現(xiàn),掛起等待鎖是重量級鎖的一種體現(xiàn)
5. 公平鎖VS非公平鎖公平鎖:公平鎖是先來后到,誰先來誰就拿到鎖
非公平鎖:多個線程同時競爭一把鎖,有一個線程是比較晚來的,卻比其他先來的線程先拿到鎖
舉個例子:
t1,t2,t3三個線程競爭同一把鎖,t1先來的,所以t1先拿到了鎖,這就叫公平鎖.
而如果t3是晚來的,然后t3比其他兩個線程先拿到了鎖,這就叫非公平鎖
操作系統(tǒng)默認(rèn)的鎖的調(diào)度,是非公平的情況
想要實現(xiàn)一個公平鎖,就需要引入額外的數(shù)據(jù)結(jié)構(gòu),來記錄線程加鎖的順序,需要一定的額外開銷
6.可重入鎖VS不可重入鎖可重入鎖:同一個線程對同一把鎖連續(xù)加鎖兩次不會造成死鎖
不可重入鎖:同一個線程對同一把鎖連續(xù)加鎖兩次會造成死鎖
舉個例子:
有一次A去上教室學(xué)習(xí)把門給鎖上了,后面要出去的時候突然想從窗戶翻出去不走大門,過了一會A忘記了這件事情,等A回來教室的時候發(fā)現(xiàn)教室里面門鎖著,就覺得里面有人,但實際上并沒有人.然后A在這里敲門等里面的人過來開門,但卻是永遠(yuǎn)也等不到里面有人來給A開門,A就會一直等下去,這就是死鎖
針對這個代碼,第一次能夠加鎖成功,而第二次加鎖的時候就會加鎖失敗,因為鎖已經(jīng)被占用,就會在第二次加鎖這里進行阻塞等待,等到第一把鎖被解鎖,第二次加鎖才會成功.而第一把鎖解鎖成功的條件是要求執(zhí)行完synchronized代碼塊,也就是要求第二把鎖加鎖成功
public class Demo3 {
static class Counter{
public synchronized void increase() {//加鎖
increase2();
}
public void increase2(){
increase3();
}
public void increase3(){
increase4();
}
public synchronized void increase4(){//加鎖
}
}
public static void main(String[] args) {
}
}
上面這個代碼就很有可能會一不小心就寫出來,因為調(diào)用了多個方法并不能直觀的看出來,就會造成死鎖
因此更好的做法是不要讓上述情況死鎖
針對上述情況,不會產(chǎn)生死鎖的話,這樣的鎖就叫做可重入鎖,反而就叫不可重入鎖
synchronized是可重入鎖
可重入鎖的實現(xiàn)要點:
Ⅰ.讓鎖里持有線程對象,記錄是誰加了鎖
Ⅱ.維護一個計數(shù)器,用來衡量啥時候是真加鎖,啥時候是真解鎖,啥時候是直接放行
引入一個計數(shù)器,每次加鎖的時候計數(shù)器就++,每次解鎖的時候計數(shù)器就--,如果計數(shù)器為0,此時的加鎖才是真加鎖,同樣計數(shù)器為0,此時的解鎖才是真解鎖
如果程序拋出了異常,沒有人catch就脫離了之前的代碼塊,脫離了一層代碼,計數(shù)器就-1,脫離到計數(shù)器為0,也就解鎖了,同理加鎖代碼中出現(xiàn)異常,也是不會死鎖的,因為Java使用關(guān)鍵字結(jié)合代碼塊來做解鎖操作,無論如何解鎖代碼都能執(zhí)行到的
7.關(guān)于synchronized的鎖策略以及自適應(yīng)①既是樂觀鎖,也是悲觀鎖
②既是輕量級鎖,也是重量級鎖
③既是自旋鎖,也是掛起等待鎖
④不是讀寫鎖,是普通互斥鎖
⑤是非公平鎖
⑥是可重入鎖
synchronized是自適應(yīng)的,初始使用的時候,是 樂觀鎖/輕量級鎖/自旋鎖,如果競爭不激烈則保持這個狀態(tài)不變,如果鎖競爭激烈了,synchronized會自動升級成為 悲觀鎖/重量級鎖/掛起等待鎖,所以synchronized是"智能"的
??
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧