Java——多线程高并发系列之Fork/Join框架简单应用

简介: Java——多线程高并发系列之Fork/Join框架简单应用

1.Fork/Join框架简介


Fork/Join 它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。Fork/Join 框架要完成两件事情:


Fork:把一个复杂任务进行分拆,大事化小 :把一个复杂任务进行分拆,大事化小


Join:把分拆任务的结果进行合并


在 Java 的 Fork/Join 框架中,使用两个类完成上述操作:


ForkJoinTask: 我们要使用 Fork/Join 框架,首先需要创建一个 ForkJoin 任务。该类提供了在任务中执行 fork 和 join 的机制。通常情况下我们不需要直接集成 ForkJoinTask 类,只需要继承它的子类,Fork/Join 框架提供了两个子类:


  1. RecursiveAction:用于没有返回结果的任务
  2. RecursiveTask:用于有返回结果的任务

ForkJoinPool:  ForkJoinTask 需要通过 ForkJoinPool 来执行。


RecursiveTask:  继承后可以实现递归(自己调自己)调用的任务。


可以在jdk官方文档中看到:



2.简单应用


实现从 1 + 2 + ... + 100 ,将它们拆分成多个小任务,分别求和,最终再将这些结果合并。


这里就是参照官方文档,先继承RecursiveTask类,重写其中的compute方法,然后定义有参构造,而ForkJoinTask需要通过 ForkJoinPool 来执行,所以还需要创建 分支合并池ForkJoinPool对象。

package test.forkjoin;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
 *
 */
class MyTask extends RecursiveTask<Integer> {
    //拆分差值不能超过10,每次计算10以内的连加操作
    private static final Integer NUMBER = 10;
    private int begin; //拆分左区间的值
    private int end; //拆分右区间的值
    private int result; //最终结果
    public MyTask(int begin,int end) {
        this.begin = begin;
        this.end = end;
    }
    @Override
    protected Integer compute() {
        //判断区间差值是否大于10
        if ((end - begin) <= NUMBER) {
            //将区间内的值依次相加
            for (int i = begin; i <= end; i++) {
                result += i;
            }
        } else { //区间差值大于10,进一步拆分
            //获取中间值
            int middle = (begin + end) / 2;
            //拆分的左区间
            MyTask taskLeft = new MyTask(begin,middle);
            //拆分的右区间
            MyTask taskRight = new MyTask(middle + 1,end);
            //fork方法进行拆分
            taskLeft.fork();
            taskRight.fork();
            //join方法进行合并
            result = taskLeft.join() + taskRight.join();
        }
        return result;
    }
}
public class ForkJoinDemo {
    public static void main(String[] args) {
        //创建MyTask对象
        MyTask myTask = new MyTask(1,100);
        //创建分支合并池对象
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);
        try {
            //获取最终合并后的结果
            Integer ans = forkJoinTask.get();
            System.out.println(ans);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭池对象
            forkJoinPool.shutdown();
        }
    }
}




目录
打赏
0
0
0
0
85
分享
相关文章
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
77 23
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
4月前
|
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
100 1
Java—多线程实现生产消费者
Java 多线程 面试题
Java 多线程 相关基础面试题
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
【JavaEE】——多线程(join阻塞,计算,引用,状态)
【JavaEE】——多线程,join,sleep引起的线程阻塞,多线程提升计算效率,如何获取线程的引用和状态
|
2月前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
58 17
|
2月前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
64 26
|
4月前
|
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
337 2

热门文章

最新文章