什么是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 应用程序。

相关推荐
冯志浩2 天前
Harmony NEXT:如何给数据库添加自定义分词
harmonyos·掘金·金石计划
中杯可乐多加冰2 个月前
【AI落地应用实战】DAMODEL深度学习平台部署+本地调用ChatGLM-6B解决方案
人工智能·掘金·金石计划
中杯可乐多加冰2 个月前
Amazon Bedrock +Amazon Step Functions实现链式提示(Prompt Chaining)
人工智能·掘金·金石计划
阿李贝斯2 个月前
el-select海量数据渲染-分页解决方案
前端·javascript·掘金·金石计划
宇宙之一粟3 个月前
Error Flows in Go
后端·go·掘金·金石计划
雨绸缪3 个月前
如何在 Eclipse 中调试ABAP程序
后端·掘金·金石计划
中杯可乐多加冰3 个月前
解决方案:昇腾aarch64服务器安装CUDA+GCC+CMake,编译安装Pytorch,华为昇腾HPC服务器深度学习环境安装全流程
人工智能·掘金·金石计划
雨绸缪4 个月前
第 1章 BW 建模工具概念介绍
后端·数据挖掘·掘金·金石计划
宇宙之一粟4 个月前
Python Asyncio 如何工作?从零开始重新创建
后端·python·掘金·金石计划