<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>

          字節(jié)一面:單核 CPU 支持 Java 多線程嗎?什么?

          共 2692字,需瀏覽 6分鐘

           ·

          2022-10-14 21:21

          推薦閱讀:公司新來了一個同事,把權(quán)限系統(tǒng)設(shè)計的爐火純青!

          由于現(xiàn)在大多計算機都是多核CPU,多線程往往會比單線程更快,更能夠提高并發(fā),但提高并發(fā)并不意味著啟動更多的線程來執(zhí)行。更多的線程意味著線程創(chuàng)建銷毀開銷加大、上下文非常頻繁,你的程序反而不能支持更高的TPS。

          時間片

          多任務(wù)系統(tǒng)往往需要同時執(zhí)行多道作業(yè)。作業(yè)數(shù)往往大于機器的CPU數(shù),然而一顆CPU同時只能執(zhí)行一項任務(wù),如何讓用戶感覺這些任務(wù)正在同時進行呢? 操作系統(tǒng)的設(shè)計者 巧妙地利用了時間片輪轉(zhuǎn)的方式

          時間片是CPU分配給各個任務(wù)(線程)的時間!

          思考:單核CPU為何也支持多線程呢?

          線程上下文是指某一時間點 CPU 寄存器和程序計數(shù)器的內(nèi)容,CPU通過時間片分配算法來循環(huán)執(zhí)行任務(wù)(線程),因為時間片非常短,所以CPU通過不停地切換線程執(zhí)行。

          換言之,單CPU這么頻繁,多核CPU一定程度上可以減少上下文切換

          超線程

          現(xiàn)代CPU除了處理器核心之外還包括寄存器、L1L2緩存這些存儲設(shè)備、浮點運算單元、整數(shù)運算單元等一些輔助運算設(shè)備以及內(nèi)部總線等。一個多核的CPU也就是一個CPU上有多個處理器核心,就意味著程序的不同線程需要經(jīng)常在CPU之間的外部總線上通信,同時還要處理不同CPU之間不同緩存導致數(shù)據(jù)不一致的問題。

          超線程這個概念是Intel提出的,簡單來說是在一個CPU上真正的并發(fā)兩個線程,由于CPU都是分時的(如果兩個線程A和B,A正在使用處理器核心,B正在使用緩存或者其他設(shè)備,那AB兩個線程就可以并發(fā)執(zhí)行,但是如果AB都在訪問同一個設(shè)備,那就只能等前一個線程執(zhí)行完后一個線程才能執(zhí)行)。實現(xiàn)這種并發(fā)的原理是 在CPU里加了一個協(xié)調(diào)輔助核心,根據(jù)Intel提供的數(shù)據(jù),這樣一個設(shè)備會使得設(shè)備面積增大5%,但是性能提高15%~30%。

          上下文切換

          • 線程切換,同一進程中的兩個線程之間的切換
          • 進程切換,兩個進程之間的切換
          • 模式切換,在給定線程中,用戶模式和內(nèi)核模式的切換
          • 地址空間切換,將虛擬內(nèi)存切換到物理內(nèi)存

          CPU切換前把當前任務(wù)的狀態(tài)保存下來,以便下次切換回這個任務(wù)時可以再次加載這個任務(wù)的狀態(tài),然后加載下一任務(wù)的狀態(tài)并執(zhí)行。任務(wù)的狀態(tài)保存及再加載, 這段過程就叫做上下文切換。

          每個線程都有一個程序計數(shù)器(記錄要執(zhí)行的下一條指令),一組寄存器(保存當前線程的工作變量),堆棧(記錄執(zhí)行歷史,其中每一幀保存了一個已經(jīng)調(diào)用但未返回的過程)。

          寄存器 是 CPU 內(nèi)部的數(shù)量較少但是速度很快的內(nèi)存(與之對應(yīng)的是 CPU 外部相對較慢的 RAM 主內(nèi)存)。寄存器通過對常用值(通常是運算的中間值)的快速訪問來提高計算機程序運行的速度。

          程序計數(shù)器是一個專用的寄存器,用于表明指令序列中 CPU 正在執(zhí)行的位置,存的值為正在執(zhí)行的指令的位置或者下一個將要被執(zhí)行的指令的位置。

          • 掛起當前任務(wù)(線程/進程),將這個任務(wù)在 CPU 中的狀態(tài)(上下文)存儲于內(nèi)存中的某處
          • 恢復一個任務(wù)(線程/進程),在內(nèi)存中檢索下一個任務(wù)的上下文并將其在 CPU 的寄存器中恢復
          • 跳轉(zhuǎn)到程序計數(shù)器所指向的位置(即跳轉(zhuǎn)到任務(wù)被中斷時的代碼行),以恢復該進程在程序中
          線程上下文切換會有什么問題呢?

          上下文切換會導致額外的開銷,常常表現(xiàn)為高并發(fā)執(zhí)行時速度會慢串行,因此減少上下文切換次數(shù)便可以提高多線程程序的運行效率。

          • 直接消耗:指的是CPU寄存器需要保存和加載, 系統(tǒng)調(diào)度器的代碼需要執(zhí)行, TLB實例需要重新加載, CPU 的pipeline需要刷掉

          • 間接消耗:指的是多核的cache之間得共享數(shù)據(jù), 間接消耗對于程序的影響要看線程工作區(qū)操作數(shù)據(jù)的大小

          切換查看

          Linux系統(tǒng)下可以使用vmstat命令來查看上下文切換的次數(shù), 其中cs列就是指上下文切換的數(shù)目(一般情況下, 空閑系統(tǒng)的上下文切換每秒大概在1500以下)

          線程調(diào)度

          搶占式調(diào)度

          指的是每條線程執(zhí)行的時間、線程的切換都由系統(tǒng)控制,系統(tǒng)控制指的是在系統(tǒng)某種運行機制下,可能每條線程都分同樣的執(zhí)行時間片,也可能是某些線程執(zhí)行的時間片較長,甚至某些線程得不到執(zhí)行的時間片。在這種機制下,一個線程的堵塞不會導致整個進程堵塞。

          java使用的線程調(diào)使用搶占式調(diào)度,Java中線程會按優(yōu)先級分配CPU時間片運行,且優(yōu)先級越高越優(yōu)先執(zhí)行,但優(yōu)先級高并不代表能獨自占用執(zhí)行時間片,可能是優(yōu)先級高得到越多的執(zhí)行時間片,反之,優(yōu)先級低的分到的執(zhí)行時間少但不會分配不到執(zhí)行時間。

          協(xié)同式調(diào)度

          指某一線程執(zhí)行完后主動通知系統(tǒng)切換到另一線程上執(zhí)行,這種模式就像接力賽一樣,一個人跑完自己的路程就把接力棒交接給下一個人,下個人繼續(xù)往下跑。線程的執(zhí)行時間由線程本身控制,線程切換可以預知,不存在多線程同步問題,但它有一個致命弱點:如果一個線程編寫有問題,運行到一半就一直堵塞,那么可能導致整個系統(tǒng)崩潰。

          線程讓出cpu的情況
          • 當前運行線程主動放棄CPU,JVM暫時放棄CPU操作(基于時間片輪轉(zhuǎn)調(diào)度的JVM操作系統(tǒng)不會讓線程永久放棄CPU,或者說放棄本次時間片的執(zhí)行權(quán)),例如調(diào)用yield()方法。
          • 當前運行線程因為某些原因進入阻塞狀態(tài),例如阻塞在I/O上
          • 當前運行線程結(jié)束,即運行完run()方法里面的任務(wù)

          引起線程上下文切換的因素

          • 當前執(zhí)行任務(wù)(線程)的時間片用完之后,系統(tǒng)CPU正常調(diào)度下一個任務(wù)
          • 中斷處理,在中斷處理中,其他程序”打斷”了當前正在運行的程序。當CPU接收到中斷請求時,會在正在運行的程序和發(fā)起中斷請求的程序之間進行一次上下文切換。中斷分為硬件中斷和軟件中斷,軟件中斷包括因為IO阻塞、未搶到資源或者用戶代碼等原因,線程被掛起。
          • 用戶態(tài)切換,對于一些操作系統(tǒng),當進行用戶態(tài)切換時也會進行一次上下文切換,雖然這不是必須的。
          • 多個任務(wù)搶占鎖資源,在多任務(wù)處理中,CPU會在不同程序之間來回切換,每個程序都有相應(yīng)的處理時間片,CPU在兩個時間片的間隔中進行上下文切換

          因此優(yōu)化手段有:
          • 無鎖并發(fā)編程,多線程處理數(shù)據(jù)時,可以用一些辦法來避免使用鎖,如將數(shù)據(jù)的ID按照Hash取模分段,不同的線程處理不同段的數(shù)據(jù)
          • CAS算法,Java的Atomic包使用CAS算法來更新數(shù)據(jù),而不需要加鎖
          • 使用最少線程
          • 協(xié)程,單線程里實現(xiàn)多任務(wù)的調(diào)度,并在單線程里維持多個任務(wù)間的切換

          合理設(shè)置線程數(shù)目既可以最大化利用CPU,又可以減少線程切換的開銷。

          • 高并發(fā),低耗時的情況,建議少線程。
          • 低并發(fā),高耗時的情況:建議多線程。
          • 高并發(fā)高耗時,要分析任務(wù)類型、增加排隊、加大線程數(shù)

          來自:布道
          鏈接:https://blog.csdn.net/alex_xfboy/article/details/90722654

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  翔田千里与黑人未删减avXX | 大香蕉青娱乐 | 欧美成人手机免费在线观看 | 国产又猛又黄又爽 | 无码另类 |