什么是ExecutorService以及Fork/Join 框架是什么

Java 是一种目前比较流行的后端编程语言,因为其强大的并发性能,使其成为开发多线程应用程序的绝佳选择。Java 中简化并发管理和执行任务过程的两个关键组件是 ExecutorService 和 Fork/Join 框架。在本文中,我们将探讨这两个框架,并以简单易懂的方式对它们进行讲解。

ExecutorService

ExecutorService 就像一组工作者(线程)的管理器,可以帮助你以受控的方式并发执行任务。它抽象化了管理线程的大部分复杂性。让我们举一个简单的例子来说明它的用法。

java 复制代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorServiceExample {
    public static void main(String[] args) {
        // Create an ExecutorService with a fixed pool of 4 threads
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        // Submit tasks for execution
        for (int i = 0; i < 10; i++) {
            final int taskNumber = i;
            executorService.execute(() -> {
                System.out.println("Task " + taskNumber + " is running on thread " + Thread.currentThread().getName());
            });
        }

        // Shutdown the ExecutorService when done
        executorService.shutdown();
    }
}

在这个例子中,我们:

1.ExecutorService使用 . 创建一个具有 4 个线程的固定池Executors.newFixedThreadPool(4)。

  1. 使用 Executors.newFixedThreadPool(4) 创建一个具有固定 4 个线程池的 ExecutorService。
  2. 使用 execute 方法提交 10 个任务供执行。
  3. ExecutorService 负责管理这些任务的线程分配和重用。
  4. 执行完毕后,我们将关闭 ExecutorService。

Fork/Join Framework

Fork/Join Framework 是一种更专业的并行处理工具。它非常适合需要将大型任务划分为较小的子任务,然后合并其结果的情况。让我们通过一个经典的例子来了解它--计算数组中元素的总和。

java 复制代码
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

public class ForkJoinExample {
    public static void main(String[] args) {
        int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ForkJoinPool pool = new ForkJoinPool();

        int result = pool.invoke(new SumTask(data, 0, data.length));
        System.out.println("Sum: " + result);
    }
}

class SumTask extends RecursiveTask<Integer> {
    private int[] data;
    private int start;
    private int end;

    public SumTask(int[] data, int start, int end) {
        this.data = data;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        if (end - start <= 3) { // Small enough, do the task directly
            int sum = 0;
            for (int i = start; i < end; i++) {
                sum += data[i];
            }
            return sum;
        } else {
            int mid = start + (end - start) / 2;
            SumTask leftTask = new SumTask(data, start, mid);
            SumTask rightTask = new SumTask(data, mid, end);
            leftTask.fork(); // Fork new tasks
            int rightResult = rightTask.compute(); // Compute one part
            int leftResult = leftTask.join(); // Wait for the other part
            return leftResult + rightResult;
        }
    }
}

在这个例子中,我们:

  1. 初始化数据数组。
  2. 创建 ForkJoinPool,这是 Fork/Join 框架的核心。
  3. 定义一个扩展 RecursiveTask 的 SumTask 类。我们在这里指定要执行的任务。
  4. SumTask 类将数组求和的任务分解为更小的子任务,并将结果合并。框架会为我们处理任务分配和结果汇总。

Fork/Join 框架如何工作

Fork/Join 框架采用分而治之的策略来实现任务并行化。以下是其工作原理的逐步分解:

  1. 主任务(本例中为 SumTask)需要解决一个求和问题。它会检查求和的大小是否小到足以直接求解(在本例中,当start和end之间的差值小于或等于 3 时)。
  2. 如果数值很小,它就会直接计算出结果。在本例中,它会对数组中 start 和 end 之间的元素求和。
  3. 如果数值太大,主任务会将其拆分为两个子任务,即 leftTask 和 rightTask,以计算求和中较小的部分。
  4. 然后左任务会被分叉,这意味着它将被提交给并行执行。这样,框架就能为每个子任务分配单独的线程。
  5. 在直接计算右任务的同时,允许左任务并行执行。
  6. 一旦两个子任务都完成,左任务和右任务的结果就会合并在一起,从而有效地合并子任务结果,得到最终结果。 这种分而治之的方法会递归地继续下去,直到所有子任务都小到足以直接计算,并将它们的结果组合起来产生总体结果。

结论

ExecutorService 和 Fork/Join 框架使 Java 中的并发变得更简单、更高效。ExecutorService 管理线程,使并发执行任务变得更容易,而 Fork/Join Framework 专为并行处理而设计,允许您划分和征服复杂的任务。

这些工具是 Java 开发人员工具箱的宝贵补充,可以有效利用多个内核并提高应用程序性能。通过掌握这些框架,您可以轻松构建高性能、多线程的 Java 应用程序。

相关推荐
光影少年6 天前
Promise状态和方法都有哪些,以及实现原理
javascript·promise·掘金·金石计划
光影少年6 天前
next.js和nuxt与普通csr区别
nuxt.js·掘金·金石计划·next.js
光影少年6 天前
js异步解决方案以及实现原理
前端·javascript·掘金·金石计划
光影少年9 天前
前端上传切片优化以及实现
前端·javascript·掘金·金石计划
ZTStory12 天前
JS 处理生僻字字符 sm4 加密后 Java 解密字符乱码问题
javascript·掘金·金石计划
光影少年13 天前
webpack打包优化都有哪些
前端·webpack·掘金·金石计划
冯志浩13 天前
Harmony Next - 手势的使用(二)
harmonyos·掘金·金石计划
冯志浩14 天前
Harmony Next - 手势的使用(一)
harmonyos·掘金·金石计划
光影少年16 天前
react虚拟列表实现及原理
前端·react.js·掘金·金石计划
光影少年16 天前
react性能优化有哪些
前端·react.js·掘金·金石计划