摘要:鎖的使用建議減少鎖持有時間減少鎖粒度讀寫鎖替代獨占鎖鎖分離鎖粗化減少鎖的持有時間減少鎖的持有時間有助于降低沖突的可能性進而提升并發(fā)能力減少鎖粒度例如內(nèi)部分為個加鎖時不會像一樣全局加鎖只需要對相應(yīng)加鎖但是如果需要獲取全局的信息比如首先會使用無
鎖的使用建議
減少鎖持有時間
減少鎖粒度
讀寫鎖替代獨占鎖
鎖分離
鎖粗化
減少鎖的持有時間
減少鎖的持有時間有助于降低沖突的可能性,進而提升并發(fā)能力
減少鎖粒度
例如ConcurrentHashMap,內(nèi)部分為16個segment,加鎖時不會像hashmap一樣全局加鎖,只需要對相應(yīng)segment加鎖,但是如果需要獲取全局的信息,比如size(),首先會使用無鎖的方法進行求值,如果失敗將要獲取所有segment的鎖
讀寫鎖替代獨占鎖(ReadWriteLock)
讀多寫少的場景下使用讀寫鎖可以顯著提高系統(tǒng)的并發(fā)能力
鎖分離
在讀寫鎖的前提上再進行升級,對獨占鎖進行分離,如LinkedBlockingQueue,由于是基于鏈表結(jié)構(gòu),take()和put()分別作用于隊列的前端和尾端.兩者并不沖突,故可以使用takeLock和putLock,從而削弱鎖競爭的可能性
public E take() throws InterruptedException { E x; int c = -1; final AtomicInteger count = this.count; final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); //take鎖加鎖 try { while (count.get() == 0) { notEmpty.await(); //如果無可用數(shù)據(jù)則一直等待,知道put()方法的通知 } x = dequeue(); c = count.getAndDecrement(); //原子操作-1 if (c > 1) notEmpty.signal(); //通知其他take方法 } finally { takeLock.unlock(); } if (c == capacity) signalNotFull(); //通知put方法 已有空間 return x; } public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); // Note: convention in all put/take/etc is to preset local var // holding count negative to indicate failure unless set. int c = -1; Nodenode = new Node (e); final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; putLock.lockInterruptibly(); try { while (count.get() == capacity) { notFull.await(); } enqueue(node); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); } finally { putLock.unlock(); } if (c == 0) signalNotEmpty(); }
鎖粗化
一連串對同一個鎖不停地進行請求和釋放會被整合成對鎖的一次操作,從而減少對鎖請求同步次數(shù)
for(int i=0;i<100;i++){ synchronized(lock){ //此時把鎖放到循環(huán)外邊去最好 //... } }JVM對鎖的優(yōu)化
鎖偏向
輕量級鎖
自旋鎖
鎖消除
鎖偏向
原理:一個線程獲得鎖,則進入偏向模式,當(dāng)這個線程再次請求鎖時,無需再做任何同步操作
場景:幾乎沒有鎖競爭的場合
操作:競爭激烈時建議關(guān)閉. -XX:+UseBiasedLocking可以開啟偏向鎖
輕量級鎖
原理:偏向鎖失敗后,會膨脹為輕量級鎖,對象頭部會嘗試指向持有鎖的線程堆棧內(nèi)部,來判斷是否持有對象鎖,如果獲得輕量級鎖成功,則進入臨界區(qū),否則表示其他線程搶占到鎖,當(dāng)前線程膨脹為重量級鎖(在膨脹前可以自旋再去嘗試獲得)
場景:不存在鎖競爭或競爭不激烈
自旋鎖
原理:鎖膨脹后,嘗試自旋,若干次后若仍得不到鎖,轉(zhuǎn)入重量級鎖,將線程掛起
場景:競爭不激烈,且持有鎖時間較短
鎖消除
原理:去除不可能存在共享的資源競爭鎖,如某些jdk內(nèi)部自帶的類
場景:單線程下的加鎖操作會被鎖消除
逃逸分析:觀察某變量是否會逃逸出某個作用域,如果該變量沒有逃逸出該作用域,則虛擬機會把該變量內(nèi)部的鎖消除掉
操作:-XX:+DoEscapeAnalysis 打開逃逸分析; -XX:+EliminateLocks 打開鎖消除
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/76169.html
摘要:大家好,我是冰河有句話叫做投資啥都不如投資自己的回報率高。馬上就十一國慶假期了,給小伙伴們分享下,從小白程序員到大廠高級技術(shù)專家我看過哪些技術(shù)類書籍。 大家好,我是...
摘要:參考何去何從的并行計算忘記該死的并行并行程序的復(fù)雜性和亂序性,并行程序設(shè)計十分復(fù)雜??膳碌默F(xiàn)實摩爾定律的失效單核上的晶體管數(shù)目達到極限。并發(fā)級別阻塞重入鎖無饑餓兩個線程優(yōu)先級不同,低優(yōu)先級的可能產(chǎn)生饑餓。 Chapter1 參考:https://github.com/chengbingh... 1.1何去何從的并行計算 1.1.1 忘記該死的并行并行程序的復(fù)雜性和亂序性,并行程序設(shè)計十...
摘要:所以需要等來確保程序中隱蔽的錯誤沒有提示的錯誤比如兩個正數(shù)相加,溢出導(dǎo)致其值為負數(shù)。并發(fā)下的兩個線程同時對一個對象,每個線程個對象,最終結(jié)果可能中有萬個對象??赡軐ο髠€數(shù)少于萬可能內(nèi)部結(jié)構(gòu)發(fā)生破壞,程序無法終止,會被大量消耗。 java并行程序基礎(chǔ) 參考:https://github.com/chengbingh... 2.1 有關(guān)線程, 需要知道的事 進程是線程的容器線程狀態(tài)圖: s...
閱讀 3412·2021-11-19 11:36
閱讀 2994·2021-09-27 13:34
閱讀 2056·2021-09-22 15:17
閱讀 2461·2019-08-30 13:49
閱讀 812·2019-08-26 13:58
閱讀 1416·2019-08-26 10:47
閱讀 2591·2019-08-23 18:05
閱讀 671·2019-08-23 14:25