Javaマルチスレッドの高度な並行プログラミング(3)ForkJoinPool(JDK7より上)

  • ForkJoinPool
    • Java7は別の並列フレームワークを提供します:分解/ガバナンス/マージ(分割統治プログラミング
    • 特殊なタスクに適しています。このタイプのタスクの計算量は簡単に決定できません(最小のタスクを決定できます)。
    • キークラス
      • ForkJoinPoolタスクプール
      • RecursiveAction
      • RecursiveTask
    • コード例
      package thread0418;
      
      import java.time.LocalDateTime;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.ForkJoinPool;
      import java.util.concurrent.ForkJoinTask;
      import java.util.concurrent.RecursiveTask;
      
      /**
       * 分任务求和
       * 使用 java.util.concurrent.ForkJoinPool (分治编程)
       * 使用 RecursiveTask (可以递归的任务接口)
       * 1) 把任务分解 一直分解直到 分解到上下限差值小于等于5
       * 2) 完成任务
       * 3) 把结果合并
       */
      public class ForkJoinPoolDemo1 {
          public static void main(String[] args) throws ExecutionException, InterruptedException {
              // 创建执行线程池
              ForkJoinPool pool = new ForkJoinPool();
      //        ForkJoinPool pool = new ForkJoinPool(4); // parallelism
      
              // 创建任务
              SumTask111 task = new SumTask111(1, 100000000);
      
              // 提交任务
              ForkJoinTask<Long> result = pool.submit(task);
      
              do {
                  System.out.printf(LocalDateTime.now() + " => " + "Main: PoolActiveThreadCount:%d" + "\n", pool.getActiveThreadCount());
                  System.out.printf(LocalDateTime.now() + " => " + "Main: 并行度(PoolParallelism): %d" + "\n", pool.getParallelism());
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              } while (!task.isDone());
      
              // 输出结果
              System.out.println(LocalDateTime.now() + " => " + result.get().toString());
          }
      }
      
      class SumTask111 extends RecursiveTask<Long> {
          private int start;
          private int end;
      
          public SumTask111(int start, int end) {
              this.start = start;
              this.end = end;
          }
      
          public static final int threadHold = 5;
      
          @Override
          protected Long compute() {
              long sum = 0L;
              // 如果任务足够小, 直接执行
              boolean canCompute = (end - start) <= threadHold;
              if (canCompute) {
                  for (int i = start; i <= end; i++) {
                      sum = sum + i;
                  }
              } else {
                  // 任务大于阈值, 分裂为 2 个任务
                  int middle = (start + end) / 2;
                  SumTask111 subTask1 = new SumTask111(start, middle);
                  SumTask111 subTask2 = new SumTask111(middle + 1, end);
      
                  invokeAll(subTask1, subTask2);
      
                  Long sum1 = subTask1.join();
                  Long sum2 = subTask2.join();
      
                  // 结果合并
                  sum = sum1 + sum2;
              }
              return sum;
          }
      }
    
    
  • まとめ
    • Fork-JoinとExecutorの違いを理解する
    • タスク分解粒度を制御する
    • Fork-Joinフレームワークに慣れ、マルチスレッド実行の効率を向上させます。

おすすめ

転載: www.cnblogs.com/sweetXiaoma/p/12726213.html