ps:原諒我沒干過后臺開發(fā),不了解線程池配置的更多內(nèi)容,先寫這么點
好像要一個呀 ~
在《java虛擬機并發(fā)編程》一書中推薦我們使用系統(tǒng)可用的處理器核心數(shù)來匹配線程池數(shù)量
Runtime.getRuntime().availableProcessors()
常見2種任務(wù):
- 計算密集型 - 創(chuàng)建處理器可用核心數(shù)那么多的線程數(shù)就可以了,在這種情況下,創(chuàng)建更多的線程對程序的性能而言反而是不利的您市,因為當(dāng)有多個任務(wù)處于就緒狀態(tài)時,處理器核心需要在線程間頻繁進行上下文切換,而這種切換對程序性能損耗較大玖喘。
- IO密集型 - 那么我們需要開更多的線程來提高性能,執(zhí)行 IO 操作線程會被阻塞蘑志,處理器可以立即進行上下文切換以便處理其他就緒線程累奈,如果我們只有處理器可用核心數(shù)那么多線程的話,則即使有待執(zhí)行的任務(wù)也無法處理急但,因為我們已經(jīng)拿不出更多的線程供處理器調(diào)度了
那么如何區(qū)別計算密集型和IO密集型任務(wù)呢澎媒,這就要提到一個概念: 阻塞系數(shù)
阻塞系數(shù) = 阻塞時間 / 總的運行時間,如果任務(wù)有 50% 的時間處于阻塞狀態(tài)波桩,則阻塞系數(shù)為0.5
如果任務(wù)被阻塞的時間 < 50%旱幼,任務(wù)就是計算密集型的,所需線程數(shù)將隨之減少突委,但最少也不應(yīng)該低于處理器的核心數(shù)柏卤。如果任務(wù)被阻塞的時間大于執(zhí)行時間冬三,即該任務(wù)是 IO 密集型的,我們就需要創(chuàng)建比處理器核心數(shù)大幾倍數(shù)量的線程
網(wǎng)上有個公式:
線程數(shù) = CPU可用核心數(shù)/(1 - 阻塞系數(shù))缘缚,其中阻塞系數(shù)的取值在0和1之間勾笆。
我們可以通過擴展線程池進行監(jiān)控,繼承線程池并重寫線程池 beforeExecute桥滨、afterExecute窝爪、terminated方法,我們可以在任務(wù)執(zhí)行前齐媒,執(zhí)行后和線程池關(guān)閉前干一些事情蒲每。如監(jiān)控任務(wù)的平均執(zhí)行時間,最大執(zhí)行時間和最小執(zhí)行時間等喻括,這幾個方法在線程池里是空方法