首先,說起並發技術,都要先知道IO密集型和CPU密集型。那麼這兩種密集型的概念是怎樣的呢?簡單的說,就是凡事涉及大量計算的,而少數時間只花在讀取IO數據的為CPU密集型,因為大量的運行只有在CPU才能進行。而凡是只需要CPU一個命令,實現如內存或硬盤的IO讀寫操作,而CPU根本無需或者少量計算的,就是屬於IO密集型。或者這麼說,如果任務被阻塞的時間少於50%,則這些任務是CPU密集型的,若任務被阻塞的時間大於執行的時間,即該任務是IO密集型的。
接下來我們就可以針對這兩種類型來討論並發策略了。
一般情況下,通過使用多線程來進行並發處理。那麼,多少線程數才能達到最佳效果呢?一般計算程序所需要的線程總數如下:
線程數=CPU可用核數/(1-阻塞系數),其中阻塞系數的取值在0和1之間。一般,CPU密集型的阻塞系數為0,所以一般情況下,CPU密集型的線程數只和CPU可用核數相關。而IO密集型任務的阻塞系數則接近1.
在IO密集型應用程序中使用並發技術:
在IO密集型應用程序中,線程數的多少受到子任務總數的影響。如在程序中劃分子任務的代碼如下:
final ExecutorService excutorPool = Executors.newFixedThreadPool(poolSize);
即子任務的個數有變量poolSize決定,如poolSize的大小為40,即任務劃分成40個子任務,則在一個單核處理上開40個線程或者在一個雙核處理器上開20個線程就可以了,總線程數超過40個對程序速度替身沒有多大的效果。
而我們或許有疑問,為什麼不增大子任務的個數呢?這個是資源問題,任何東西資源都是有限的。
在CPU密集型應用程序中使用並發技術:
典型的屬於CPU密集型應用程序的就是給出個,判斷是否為素數。這種程序需要計算機大量的計算,占據CPU處理的時間比較長,特別是給出兩個數的,計算這兩個數之間有哪些數是素數。這種CPU密集型應用程序使用的線程數受到子任務的束縛,而子任務是受到CPU核的束縛。即如果是雙核的,那麼總線程數為2。另外還要考慮到劃分任務時工作負載均勻分布。如計算兩個數之間有哪些素數,若只是普通的平均分一半,則另一半因為數值太大,CPU所處理的時間就會比前一部分慢,所以考慮工作負載的均勻性是很重要的。
CPU密集型的幾點重要經驗:
1.子任務的劃分數應不少於處理器核心數。
2.線程數多於處理器核心數對性能提升是毫無幫助的。
3.在子任務劃分數超過一定的數量之後,再增加子問題華分數對性能的提升將十分有限。