
- Java 併發教程
- 併發 - 首頁
- 併發 - 概述
- 併發 - 環境設定
- 併發 - 主要操作
- 執行緒間通訊
- 併發 - 同步
- 併發 - 死鎖
- 工具類示例
- 併發 - ThreadLocal
- 併發 - ThreadLocalRandom
- 鎖示例
- 併發 - Lock
- 併發 - ReadWriteLock
- 併發 - Condition
- 原子變數示例
- 併發 - AtomicInteger
- 併發 - AtomicLong
- 併發 - AtomicBoolean
- 併發 - AtomicReference
- 併發 - AtomicIntegerArray
- 併發 - AtomicLongArray
- 併發 - AtomicReferenceArray
- Executor 示例
- 併發 - Executor
- 併發 - ExecutorService
- ScheduledExecutorService
- 執行緒池示例
- 併發 - newFixedThreadPool
- 併發 - newCachedThreadPool
- newScheduledThreadPool
- newSingleThreadExecutor
- 併發 - ThreadPoolExecutor
- ScheduledThreadPoolExecutor
- 高階示例
- 併發 - Futures 和 Callables
- 併發 - Fork-Join 框架
- 併發集合
- 併發 - BlockingQueue
- 併發 - ConcurrentMap
- ConcurrentNavigableMap
- 併發有用資源
- 併發 - 快速指南
- 併發 - 有用資源
- 併發 - 討論
Java 併發 - Fork-Join 框架
Fork-Join 框架允許將某個任務分解成多個工作執行緒,然後等待結果並將它們組合起來。它在很大程度上利用了多處理器機器的能力。以下是 Fork-Join 框架中使用的核心概念和物件。
Fork(分叉)
Fork 是一個過程,其中一個任務將自身拆分為更小且獨立的子任務,這些子任務可以併發執行。
語法
Sum left = new Sum(array, low, mid); left.fork();
這裡 Sum 是 RecursiveTask 的一個子類,left.fork() 將任務拆分為子任務。
Join(合併)
Join 是一個過程,其中一個任務在子任務完成執行後合併所有子任務的結果,否則它將一直等待。
語法
left.join();
這裡 left 是 Sum 類的物件。
ForkJoinPool
它是一個專門為處理 Fork-Join 任務拆分而設計的執行緒池。
語法
ForkJoinPool forkJoinPool = new ForkJoinPool(4);
這裡建立一個新的 ForkJoinPool,其並行級別為 4 個 CPU。
RecursiveAction
RecursiveAction 表示一個不返回值的任務。
語法
class Writer extends RecursiveAction { @Override protected void compute() { } }
RecursiveTask
RecursiveTask 表示一個返回值的任務。
語法
class Sum extends RecursiveTask<Long> { @Override protected Long compute() { return null; } }
示例
以下 TestThread 程式展示了在基於執行緒的環境中使用 Fork-Join 框架。
import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; public class TestThread { public static void main(final String[] arguments) throws InterruptedException, ExecutionException { int nThreads = Runtime.getRuntime().availableProcessors(); System.out.println(nThreads); int[] numbers = new int[1000]; for(int i = 0; i < numbers.length; i++) { numbers[i] = i; } ForkJoinPool forkJoinPool = new ForkJoinPool(nThreads); Long result = forkJoinPool.invoke(new Sum(numbers,0,numbers.length)); System.out.println(result); } static class Sum extends RecursiveTask<Long> { int low; int high; int[] array; Sum(int[] array, int low, int high) { this.array = array; this.low = low; this.high = high; } protected Long compute() { if(high - low <= 10) { long sum = 0; for(int i = low; i < high; ++i) sum += array[i]; return sum; } else { int mid = low + (high - low) / 2; Sum left = new Sum(array, low, mid); Sum right = new Sum(array, mid, high); left.fork(); long rightResult = right.compute(); long leftResult = left.join(); return leftResult + rightResult; } } } }
這將產生以下結果。
輸出
32 499500
廣告