近期看了一些JVM和並發編程的專欄,結合自身理解,來做一個關於(線程池線程數與(CPU密集型任務和I/O密集型任務)的關系)的總結:
1.任務類型舉例:
1.1: CPU密集型:
例如,一般我們系統的靜態資源,比如js,css等,會存在一個版本號,如 main.js?v0,每當用戶訪問這個資源的時候,會發送一個比對請求到服務端,比對本地靜態文件版本和服務端的文件版本是否一致,不一致則更新.這種任務一般不占用大量IO,所以后台服務器可以快速處理,壓力落在CPU上.
1.2: I/O密集型:
比方說近期我們做的萬科CRM系統,常有大數據量的查詢和批量插入操作,此時的壓力主要在I/O上.
2.線程數與任務類型的關系:
2.1:與CPU密集型的關系:
一般情況下,CPU核心數 == 最大同時執行線程數.在這種情況下(設CPU核心數為n),大量客戶端會發送請求到服務器,但是服務器最多只能同時執行n個線程.
設線程池工作隊列長度為m,且m>>n,則此時會導致CPU頻繁切換線程來執行(如果CPU使用的是FCFS,則不會頻繁切換,如使用的是其他CPU調度算法,如時間片輪轉法,最短時間優先,則可能會導致頻繁的線程切換).
所以這種情況下,無需設置過大的線程池工作隊列,(工作隊列長度 = CPU核心數 || CPU核心數+1) 即可.
2.2:與I/O密集型的關系:
1個線程對應1個方法棧,線程的生命周期與方法棧相同.
比如某個線程的方法棧對應的入站順序為:controller()->service()->DAO(),由於DAO長時間的I/O操作,導致該線程一直處於工作隊列,但它又不占用CPU,則此時有1個CPU是處於空閑狀態的.
所以,這種情況下,應該加大線程池工作隊列的長度(如果CPU調度算法使用的是FCFS,則無法切換),盡量不讓CPU空閑下來,提高CPU利用率.
若理解有誤,請指正.