java併發編程:定製線程池的大小

java併發編程:定製線程池的大小

     線程池合理的長度取決於將要提交的任務類型和所部署系統的特徵。

     爲了正確的定製線程池的長度,你需要理解你的計算環境、資源預算和任務的自身特性。部署系統中安裝了多少個CPU?多少內存?任務主要執行的是計算、I/O還是一些混合操作?它們是否需要像JDBC Connection這樣的稀缺資源?如果你有不同類別的任務,它們擁有差別很大的行爲,那麼應該考慮使用多個不同的線程池,這樣每個線程池可以根據不同任務的工作負載進行調節。

      對於計算密集型的任務,一個有Ncpu 個處理器的系統通常通過使用一個Ncpu +1個線程的線程池來獲得最優的利用率(計算密集型的線程恰好在某時因爲發生一個頁錯誤或者因爲其他原因而暫停,剛好有一個“額外”的線程,可以確保在這樣的情況下CPU週期不會中斷工作)。對於包含了I/O和其他阻塞操作的任務,不是所有的線程都會在所有的時間被調度,因此你需要一個更大的池。爲了正確地設置線程池的長度,你必須估算出任務花在等待的時間與用來計算的時間的比率;這個估算值不必十分精確,而且可以通過一些監控工具獲得。你還可以選擇另一種方法來調節線程池的大小,在一個基準負載下,使用不同大小的線程池運行你的應用程序,並觀察CPU利用率的水平。

         給定下列定義:

         Ncpu = CPU的數量

       Ucpu = 目標CPU的使用率,0 ≤ Ucpu≤ 1

       W/C = 等待時間與計算時間的比率

    爲保持處理器達到期望的使用率,最優的池的大小等於:

        Nthreads = Ncpu * Ucpu * ( 1 + W/C )

    可以使用Runtime來獲得CPU的數目:

        int N_CPUS = Runtime.getRuntime().availableProcessors();

        CPU週期並不是唯一可以使用線程池管理的資源。其他可以約束資源池大小的資源包括:內存、文件句柄、套接字句柄和數據庫連接等。計算這些資源池的大小約束非常簡單:首先累加出每一個任務需要的這些資源的總量,然後除以可用的總量。所得的結果是池大小的上限。

 

       參見《Java Concurrency in Practice》 第八章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章