简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀
推荐1:车载系统实战课:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
推荐2:HIDL与AIDL实战课:Android14 Binder之HIDL与AIDL通信实战课 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
🌻1. 前言
本篇目的:Java线程池之ForkJoinPool:用法实例
🌻2. Java线程池ForkJoinPool介绍
-
基本概念
ForkJoinPool是Java并发包提供的支持分治并行计算的线程池,基于工作窃取算法,适合递归任务拆分。 -
功能
提供提交ForkJoinTask、invoke、execute、invokeAll等方法,支持RecursiveTask、RecursiveAction两种任务类型。 -
使用限制
任务需可拆分且避免阻塞,否则降低并行度。 -
性能特性
工作窃取平衡负载,线程数默认等于CPU核数,可设置parallelism调整。 -
使用场景
大数据并行计算、归并排序、MapReduce框架、图形处理等。
🌻3. 代码实例
🌻3.1 使用ForkJoinPool并行计算累加和
-
应用场景
并行求1到n的和。 -
用法实例
import java.util.concurrent.*; public class SumTask extends RecursiveTask<Long> { private final int start, end; private static final int THRESHOLD = 1000; public SumTask(int start, int end) { this.start = start; this.end = end; } protected Long compute() { if (end - start <= THRESHOLD) { long sum = 0; for (int i = start; i <= end; i++) sum += i; return sum; } int mid = (start + end) >>> 1; SumTask left = new SumTask(start, mid); SumTask right = new SumTask(mid + 1, end); left.fork(); return right.compute() + left.join(); } public static void main(String[] args) { ForkJoinPool pool = new ForkJoinPool(); long result = pool.invoke(new SumTask(1, 10000)); System.out.println(result); } }
输出:
50005000
🌻3.2 使用ForkJoinPool并行排序数组
-
应用场景
并行归并排序。 -
用法实例
import java.util.concurrent.*; public class MergeSort extends RecursiveAction { private final int[] arr; private final int left, right; public MergeSort(int[] arr, int left, int right) { this.arr = arr; this.left = left; this.right = right; } protected void compute() { if (left < right) { int mid = (left + right) >>> 1; invokeAll(new MergeSort(arr, left, mid), new MergeSort(arr, mid + 1, right)); merge(left, mid, right); } } private void merge(int l, int m, int r) { int[] tmp = new int[r - l + 1]; int i = l, j = m + 1, k = 0; while (i <= m && j <= r) tmp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; while (i <= m) tmp[k++] = arr[i++]; while (j <= r) tmp[k++] = arr[j++]; System.arraycopy(tmp, 0, arr, l, tmp.length); } public static void main(String[] args) { int[] data = {5, 3, 8, 6, 2, 7, 4, 1}; ForkJoinPool.commonPool().invoke(new MergeSort(data, 0, data.length - 1)); for (int v : data) System.out.print(v); } }
输出:
12345678
🌻3.3 使用ForkJoinPool并行统计文件行数
-
应用场景
递归统计目录下所有文件总行数。 -
用法实例
import java.io.*; import java.nio.file.*; import java.util.concurrent.*; public class LineCounter extends RecursiveTask<Long> { private final Path path; public LineCounter(Path path) { this.path = path; } protected Long compute() { try { if (Files.isRegularFile(path)) { return Files.lines(path).count(); } else if (Files.isDirectory(path)) { try (var s = Files.list(path)) { return s.map(LineCounter::new) .collect(ForkJoinTask::invokeAll, (a, b) -> a.add(b.join()), (a, b) -> a + b); } } } catch (IOException ignored) {} return 0L; } public static void main(String[] args) { ForkJoinPool pool = ForkJoinPool.commonPool(); long lines = pool.invoke(new LineCounter(Paths.get("src"))); System.out.println(lines); } }
输出示例:
1234
🌻3.4 线程池ForkJoinPool总结
关键词 | 功能描述 | 典型应用 |
---|---|---|
ForkJoinPool | 分治并行线程池 | 大数据累加、归并排序、文件统计 |
RecursiveTask | 有返回结果任务 | 并行求和、统计 |
RecursiveAction | 无返回结果任务 | 并行排序、图形处理 |
commonPool | 全局共享池 | 无需显式创建即可使用 |
parallelism | 并行度参数 | 控制线程数量提升或降低吞吐量 |