Java多線程上下文切換


 

轉載請注明原文地址:https://www.cnblogs.com/ygj0930/p/10843676.html

 

一:什么是上下文切換

   CPU處理任務時不是一直只處理一個,而是通過給每個線程分配CPU時間片,時間片用完了就切換下一個線程。時間片非常短,一般只有幾十毫秒,所以CPU通過不停地切換線程執行時我們幾乎感覺不到任務的停滯,讓我們感覺是多個線程同時執行。

   CPU通過時間片分配算法來循環執行任務,當前任務執行一個時間片后會切換到下一個任務。但是,在切換前會保存上一個任務的狀態,以便下次切換回這個任務時,可以再次加載這個任務的狀態,從任務保存到再加載的過程就是一次上下文切換

   這樣的切換是會影響多線程的執行效率的。

 

二:如何減少上下文切換來提高多線程程序的運行效率

    線程的上下文切換分為讓步式上下文切換搶占式上下文切換

    前者是指執行線程主動釋放CPU,與鎖競爭嚴重程度成正比,可通過減少鎖競爭來避免

    后者是指線程因分配的時間片用盡而被迫放棄CPU或者被其他優先級更高的線程所搶占,一般由於線程數大於CPU可用核心數引起,可通過調整線程數,適當減少線程數來避免。

 

    1)無鎖並發編程。鎖競爭時會引起上下文切換,所以多線程處理數據時,可以用一些辦法來避免使用鎖,如將數據的ID按照Hash取模分段,不同的線程處理不同段的數據。

    2)減少鎖的使用,能用CAS代替鎖時盡量用CAS代替。Java的Atomic包使用CAS算法來更新數據,而不需要加鎖。

         在多線程競爭下,加鎖、釋放鎖會導致比較多的上下文切換和調度延時,引起性能問題。

          多個線程使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程並不會被掛起,而是被告知這次競爭中失敗,並可以再次嘗試(只要cpu分配給線程的時間片沒有過,就可以不斷的重試,但是時間片過后,如果還是沒有成功,也會進行上下文切換,所以說只是減少了上下文切換)。

    3)使用最少線程。避免創建不需要的線程,比如任務很少,但是創建了很多線程來處理,這樣會造成大量線程都處於等待狀態。

    4)使用協程。在單線程里實現多任務的調度,並在單線程里維持多個任務間的切換。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM