Threadpools
線程池適合用在把任務進行分解,並發進行執行的場景。通常來說,系統裡面會針對不同的任務設置一個單獨的守護線程用來專門處理這項任務。例如使用Networking Thread用來專門處理網絡請求的操作,使用IO Thread用來專門處理系統的I\O操作。針對那些場景,這樣設計是沒有問題的,因為對應的任務單次執行的時間並不長而且可以是順序執行的。但是這種專屬的單線程並不能滿足所有的情況,例如我們需要一次性decode 40張圖片,每個線程需要執行4ms的時間,如果我們使用專屬單線程的方案,所有圖片執行完畢會需要花費160ms(40*4),但是如果我們創建10個線程,每個線程執行4個任務,那麼我們就只需要16ms就能夠把所有的圖片處理完畢。
為了能夠實現上面的線程池模型,系統為我們提供了ThreadPoolExecutor
幫助類來簡化實現,剩下需要做的就只是對任務進行分解就好了。
使用線程池需要特別注意同時並發線程數量的控制,理論上來說,我們可以設置任意你想要的Concurrent數量,但是這樣做非常的不好。因為CPU只能同時執行固定數量的線程數,一旦同時並發的線程數量超過CPU能夠同時執行的閾值,CPU就需要花費精力來判斷到底哪些線程的優先級比較高,需要在不同的線程之間進行調度切換。
一旦同時並發的線程數量達到一定的量級,這個時候CPU在不同線程之間進行調度的時間就可能過長,反而導致性能嚴重下降。另外需要關注的一點是,每開一個新的線程,都會耗費至少64K+的內存。為了能夠方便的對線程數量進行控制,ThreadPoolExecutor為我們提供了初始化的並發線程數量,以及最大的並發數量進行設置。
另外需要關注的一個問題是:Runtime.getRuntime().availableProcesser()
方法並不可靠,他返回的值並不是真實的CPU核心數,因為CPU會在某些情況下選擇對部分核心進行睡眠處理,在這種情況下,返回的數量就只能是激活的CPU核心數。