實戰(zhàn)java高并發(fā)程序設計第四章-鎖優(yōu)化(一)

前言:java 多線程鎖的優(yōu)化一直是難點竹观!如果優(yōu)化的好镐捧,性能會高很多潜索,比如 jdk 里面提供了很多 juc 的類,以及著名框架 Disruptor,netty 也有很多優(yōu)化懂酱,所以本篇文章就大概的講一下我們在高并發(fā)程序設計對于鎖的優(yōu)化竹习,也希望能幫助到每個看到這篇文章的你。

鎖的使用建議

1.減少鎖持有時間
2.減少鎖粒度
3.讀寫鎖替代獨占鎖
4.鎖分離
5.鎖粗化

減少鎖粒度

例如ConcurrentHashMap,內部分為16個segment,加鎖時不會像hashmap一樣全局加鎖,只需要對相應segment加鎖,但是如果需
要計算map所有的大小size(),則需依次獲取所有segment的鎖

減少鎖的持有時間

減少鎖的持有時間有助于降低沖突的可能性,進而提升并發(fā)能力

讀寫鎖替代獨占鎖(ReadWriteLock)

讀多寫少的場景下使用讀寫鎖可以顯著提高系統(tǒng)的并發(fā)能力

鎖分離

在讀寫鎖的前提上再進行升級,對獨占鎖進行分離,如LinkedBlockingQueue,由于是基于鏈表結構,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;
        Node<E> node = new Node<E>(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)化

1.鎖偏向
2.輕量級鎖
3.自旋鎖
4.鎖消除

鎖偏向

原理:一個線程獲得鎖,則進入偏向模式,當這個線程再次請求鎖時,無需再做任何同步操作
場景:幾乎沒有鎖競爭的場合
操作:競爭激烈時建議關閉. -XX:+UseBiasedLocking可以開啟偏向鎖

輕量級鎖

原理:偏向鎖失敗后,會膨脹為輕量級鎖,對象頭部會嘗試指向持有鎖的線程堆棧內部,來判斷是否持有對象鎖,如果獲得輕量級鎖成功,則進入臨界區(qū),否則表示其他線程搶占到鎖,當前線程膨脹為重量級鎖(在膨脹前可以自旋再去嘗試獲得)
場景:不存在鎖競爭或競爭不激烈

自旋鎖

原理:鎖膨脹后,嘗試自旋,若干次后若仍得不到鎖,轉入重量級鎖,將線程掛起
場景:競爭不激烈,且持有鎖時間較短

-鎖消除

原理:去除不可能存在共享的資源競爭鎖,如某些jdk內部自帶的類
場景:單線程下的加鎖操作會被鎖消除
逃逸分析:觀察某變量是否會逃逸出某個作用域,如果該變量沒有逃逸出該作用域,則虛擬機會把該變量內部的鎖消除掉
操作:-XX:+DoEscapeAnalysis 打開逃逸分析; -XX:+EliminateLocks 打開鎖消除

ThreadLocal

線程的局部變量,僅當前線程可以訪問,故實現(xiàn)線程安全.

.....

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末列牺,一起剝皮案震驚了整個濱河市整陌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞎领,老刑警劉巖泌辫,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異九默,居然都是意外死亡震放,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門驼修,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殿遂,“玉大人,你說我怎么就攤上這事乙各∧福” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵耳峦,是天一觀的道長恩静。 經(jīng)常有香客問我,道長蹲坷,這世上最難降的妖魔是什么驶乾? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮冠句,結果婚禮上轻掩,老公的妹妹穿的比我還像新娘幸乒。我一直安慰自己懦底,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布罕扎。 她就那樣靜靜地躺著聚唐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腔召。 梳的紋絲不亂的頭發(fā)上杆查,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音臀蛛,去河邊找鬼亲桦。 笑死崖蜜,一個胖子當著我的面吹牛,可吹牛的內容都是我干的客峭。 我是一名探鬼主播豫领,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼舔琅!你這毒婦竟也來了等恐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤备蚓,失蹤者是張志新(化名)和其女友劉穎课蔬,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郊尝,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡二跋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了虚循。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片同欠。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖横缔,靈堂內的尸體忽然破棺而出丙曙,到底是詐尸還是另有隱情必盖,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站奇颠,受9級特大地震影響,放射性物質發(fā)生泄漏搀罢。R本人自食惡果不足惜艘绍,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望初狰。 院中可真熱鬧莫杈,春花似錦、人聲如沸奢入。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腥光。三九已至关顷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間武福,已是汗流浹背议双。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捉片,地道東北人平痰。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓汞舱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宗雇。 傳聞我的和親對象是個殘疾皇子兵拢,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內容