1. 程式人生 > 實用技巧 >jhat 分析jmap生成的dump檔案

jhat 分析jmap生成的dump檔案

java 執行緒池

  1. 作用

    1. 降低資源消耗。

    2. 提高響應速度。
    3. 提高執行緒的可管理性。
  2. 引數說明
    1. corePoolSize//初始執行緒池大小
    2. maximumPoolSize // 最大執行緒池大小
    3. keepAliveTime // 執行緒最大空閒時間
    4. unit // 時間單位
      1. TimeUnit.MILLISECONDS (毫秒)
      2. TimeUnit.SECONDS (秒)
      3. TimeUnit.MINUTES (分鐘)
      4. TimeUnit.HOURS (小時)
      5. TimeUnit.DAYS (天)
    5. workQueue// 執行緒等待佇列
      1. SynchronousQueue(直接握手佇列)
      2. LinkedBlockingQueue(無界佇列)
      3. ArrayBlockingQueue(有界佇列)
      4. PriorityBlockingQueue(優先順序佇列)
    6. [threadFactory]// 執行緒建立工廠
    7. [handler]// 拒絕策略
      1. AbortPolicy策略:該策略會直接丟擲異常,阻止系統正常工作;
      2. CallerRunsPolicy策略:如果執行緒池的執行緒數量達到上限,該策略會把任務佇列中的任務放在呼叫者執行緒當中執行;
      3. DiscardOledestPolicy策略:該策略會丟棄任務佇列中最老的一個任務,也就是當前任務佇列中最先被新增進去的,馬上要被執行的那個任務,並嘗試再次提交;
      4. DiscardPolicy策略:該策略會默默丟棄無法處理的任務,不予任何處理。當然使用此策略,業務場景中需允許任務的丟失;
  3. 執行緒池的分析
    1.  1 // 有任務提交-->
       2 if(corePoolSize 沒滿){
       3     建立新的執行緒執行任務
       4 } else if(workQueue 沒滿) {
       5     進入workQueue等待
       6 } else if(maximumPoolSize 沒滿){
       7     建立新的執行緒執行任務
       8 } else {
       9     handler拒絕策略
      10 }

  4. 執行緒池的監控
    1. log.info("曾經最大執行緒:{}, 現有執行緒:{}, 總任務:{}, 正在執行:{}, 已完成:{}",
                      THREAD_POOL.getLargestPoolSize(),
                      THREAD_POOL.getPoolSize(),
                      THREAD_POOL.getTaskCount(),
                      THREAD_POOL.getActiveCount(),
                      THREAD_POOL.getCompletedTaskCount()
                      );
      
      getLargestPoolSize():曾經最大執行緒數量
      getPoolSize():現有執行緒數量
      getTaskCount():總需要執行的任務數量
      getActiveCount():正在工作的執行緒數量
      getCompletedTaskCount():已完成的任務數量

  5. 執行緒池使用例子
    1. // 初始化執行緒池
      private static final ThreadPoolExecutor THREAD_POOL = initThreadPool();
      
      // 測試main
      public static void main(String[] args) {
          for (int i = 0; i < 5; i++) {
              int number = i;
              THREAD_POOL.execute(() -> {
                  // 要用執行緒執行的程式碼
                  System.out.println(Thread.currentThread().getName() + " 列印了 " + number);
              });
          }
          // THREAD_POOL.shutdown(); 此句是關閉執行緒池,在專案中一般不用關閉.
      }
      
      private static ThreadPoolExecutor initThreadPool() {
          // CPU 獲取電腦數量
          int cpuCount = Runtime.getRuntime().availableProcessors();
      
          // 初始執行緒數
          int corePoolSize = cpuCount;
          
          // 最大執行緒池大小
          int maximumPoolSize = 30;
          
           // 執行緒最大空閒時間
          long keepAliveTime = 60;
          
          // 時間單位:  秒
          TimeUnit unit = TimeUnit.SECONDS;
          
          // 執行緒等待佇列
          SynchronousQueue<Runnable> workQueue = new SynchronousQueue<>();
          
          // 執行緒序列
          AtomicInteger atomicInteger = new AtomicInteger(1);
          
          // 執行緒工廠
          ThreadFactory namedThreadFactory = (Runnable r) -> new Thread(r, "我的執行緒-" + atomicInteger.getAndIncrement());
          
          // 建立執行緒池
          ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, namedThreadFactory);
          
          // 預啟動執行緒池
          threadPool.prestartAllCoreThreads();
          
          // 返回執行緒池.
          return threadPool;
      }