<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖解:為什么非公平鎖的性能更高?

          共 2305字,需瀏覽 5分鐘

           ·

          2021-08-22 00:25

          作者 | 王磊

          來源 | Java中文社群(ID:javacn666)

          轉(zhuǎn)載請聯(lián)系授權(quán)(微信ID:GG_Stone)

          在 Java 中 synchronized 和 ReentrantLock 默認使用的都是非公平鎖,而它們采用非公平鎖的原因都是一致的,都是為了提升程序的性能。那為什么非公平鎖就能提升性能呢?接下來我們一起來看。

          非公平鎖

          非公平鎖:每個線程獲取鎖的順序是隨機的,并不會遵循先來先得的規(guī)則,任何線程在某時刻都有可能直接獲取并擁有鎖。這就好比磊哥去加油,到了加油站之后發(fā)現(xiàn)前面有人在加,于是我就在車里刷起了抖音,過了一會,前面的車加完油走了,但磊哥沒注意到,還在車里愉快的刷著抖音。然而此時加油站又來了一輛車,發(fā)現(xiàn)有空閑的油槍,于是就搶先在磊哥之前把油加了。這里的油槍就是鎖,沒有按照到達的先后順序得到油槍,這就是非公平鎖。

          公平鎖

          公平鎖:每個線程獲取鎖的順序是按照線程訪問鎖的先后順序獲取的,最前面的線程總是最先獲取到鎖。這就好像上高速排隊過收費站一樣,所有的車要排隊等待通行,最先來的車最先通過收費站。

          性能對比

          公平鎖和非公平鎖的性能測試結(jié)果如下,以下測試數(shù)據(jù)來自于《Java并發(fā)編程實戰(zhàn)》:

          從上述結(jié)果可以看出,使用非公平鎖的吞吐率(單位時間內(nèi)成功獲取鎖的平均速率)要比公平鎖高很多。

          性能分析

          以上測試數(shù)據(jù)雖然說明了結(jié)果,但并不能說明為什么非公平鎖的性能會更高?所以,接下來,我們通過分析公平鎖和非公平的執(zhí)行流程,來得到這個問題的答案。

          公平鎖執(zhí)行流程

          獲取鎖時,先將線程自己添加到等待隊列的隊尾并休眠,當某線程用完鎖之后,會去喚醒等待隊列中隊首的線程嘗試去獲取鎖,鎖的使用順序也就是隊列中的先后順序,在整個過程中,線程會從運行狀態(tài)切換到休眠狀態(tài),再從休眠狀態(tài)恢復(fù)成運行狀態(tài),但線程每次休眠和恢復(fù)都需要從用戶態(tài)轉(zhuǎn)換成內(nèi)核態(tài),而這個狀態(tài)的轉(zhuǎn)換是比較慢的,所以公平鎖的執(zhí)行速度會比較慢。

          用戶態(tài) & 內(nèi)核態(tài)

          用戶態(tài)(User Mode):當進程在執(zhí)行用戶自己的代碼時,則稱其處于用戶運行態(tài)。內(nèi)核態(tài)(Kernel Mode):當一個任務(wù)(進程)執(zhí)行系統(tǒng)調(diào)用而陷入內(nèi)核代碼中執(zhí)行時,我們就稱進程處于內(nèi)核運行態(tài),此時處理器處于特權(quán)級最高的內(nèi)核代碼中執(zhí)行。

          為什么分內(nèi)核態(tài)和用戶態(tài)?

          假設(shè)沒有內(nèi)核態(tài)和用戶態(tài)之分,程序就可以隨意讀寫硬件資源了,比如隨意讀寫和分配內(nèi)存,這樣如果程序員一不小心將不適當?shù)膬?nèi)容寫到了不該寫的地方,很可能就會導(dǎo)致系統(tǒng)崩潰。

          而有了用戶態(tài)和內(nèi)核態(tài)的區(qū)分之后,程序在執(zhí)行某個操作時會進行一系列的驗證和檢驗之后,確認沒問題之后才可以正常的操作資源,這樣就不會擔心一不小心就把系統(tǒng)搞壞的情況了,也就是有了內(nèi)核態(tài)和用戶態(tài)的區(qū)分之后可以讓程序更加安全的運行,但同時兩種形態(tài)的切換會導(dǎo)致一定的性能開銷。

          非公平鎖執(zhí)行流程

          當線程獲取鎖時,會先通過 CAS 嘗試獲取鎖,如果獲取成功就直接擁有鎖,如果獲取鎖失敗才會進入等待隊列,等待下次嘗試獲取鎖。這樣做的好處是,獲取鎖不用遵循先到先得的規(guī)則,從而避免了線程休眠和恢復(fù)的操作,這樣就加速了程序的執(zhí)行效率。

          比如前幾天磊哥去一個小營業(yè)廳辦理網(wǎng)絡(luò)移機的業(yè)務(wù),去了之后發(fā)現(xiàn)前面有人在辦業(yè)務(wù),于是磊哥就告訴前面(辦理業(yè)務(wù))的小姐姐,“我門口休息一下,您等會辦理完業(yè)務(wù),麻煩去門口叫一下我”,小姐姐人也比較好,一口就答應(yīng)下來了。

          但在小姐姐辦完業(yè)務(wù)之后叫我,和我回到柜臺辦理業(yè)務(wù)之間,是有一段空閑時間的,這和等待隊列中的線程被喚醒和恢復(fù)執(zhí)行之間是有一段空閑時間是一樣的,而在這個空閑的時間中,營業(yè)廳又來了一個老李頭來交話費,等老李交完話費,我恰好也剛回來可以直接辦理業(yè)務(wù)了,這樣就是一個“三贏”的局面。

          老李頭不用排在我后面等著繳話費,我也不用等老李頭交完話費再辦理移機,而且在單位時間內(nèi)提高了營業(yè)員辦理業(yè)務(wù)的效率,她也能早早的回家,這就是所謂的“三贏”。在更短的時間內(nèi)執(zhí)行更多的任務(wù),這就是非公平鎖的優(yōu)勢。

          總結(jié)

          本文我們介紹了公平鎖和非公平鎖的定義以及執(zhí)行流程,從二者執(zhí)行流程的細節(jié)可以看出,非公平鎖因為不用按(順)序執(zhí)行,所以后來的鎖也可以直接嘗試獲得鎖,沒有了阻塞和恢復(fù)執(zhí)行的步驟,所以它的性能會更高。

          本系列原創(chuàng)文章推薦

          1.線程的故事:我的3位母親成就了優(yōu)秀的我!
          2.線程池的7種創(chuàng)建方式,強烈推薦你用它...
          3.輕量級鎖一定比重量級鎖快嗎?
          4.這樣終止線程,竟然會導(dǎo)致服務(wù)宕機?
          5.漫畫:如何證明sleep不釋放鎖,而wait釋放鎖?
          6.池化技術(shù)到達有多牛?看了這個對比嚇我一跳!
          7.求求你,別再用wait和notify了!
          8.Semaphore自白:限流器用我就對了!
          9.CountDownLatch:別浪,等人齊再團!
          10.CyclicBarrier:人齊了,老司機就發(fā)車了!
          11.Java中用戶線程和守護線程區(qū)別這么大?
          12.ThreadLocal不好用?那是你沒用對!
          13.ThreadLocal內(nèi)存溢出代碼演示和原因分析!
          14.SimpleDateFormat線程不安全的5種解決方案!
          15.synchronized 加鎖 this 和 class 的區(qū)別!
          16.synchronized 優(yōu)化手段之鎖膨脹機制!
          17.synchronized 中的 4 個優(yōu)化,你知道幾個?
          18.ReentrantLock 中的 4 個坑!

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青草2017男人天堂 | 在线成人看片免费看黄a | 精品欧美日韩一区二区三区播放 | 九九九在线| 五月婷婷天中文字幕版 |