Flux 和 Mono区别:并发并行同步异步区别

文章介绍了Flux和Mono在Java响应式编程中的作用,它们分别处理异步序列的多元素和单元素情况,以及它们在简化异步编程、响应式编程和操作数据流中的应用。示例代码展示了如何在实际项目中使用这两种工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flux 和 Mono区别

在工作中,看到导师写项目的时候用到了Flux和Mono。知识盲区了。随后去查了相关的技术信息。很遗憾说的有点太官方了。没有看懂。中午就餐之后,就问导师这两个是什么意思,以及什么区别。废话不多说,总结一下:

什么是Flux呢?

Flux代表一个包含个或多个元素的异步序列。你可以将其视为一种异步的、可以包含多个元素的容器。通常用于处理多个并行的异步操作或者事件流。

什么是Mono

Mono代表一个包含个或一个元素的异步序列。你可以将其视为一种异步的、最多包含一个元素的容器。通常用于处理只会产生一个结果的异步操作。
在响应式编程中,Flux和Mono是Reactor库中的两个核心类,用于处理异步数据流。Flux用于处理多个元素的情况,而Mono则用于处理单个元素的情况。

为什么要使用它们呢?

使用Flux和Mono有几个好处:

  • 异步编程简化:Flux和Mono提供了简洁的API,使异步编程更加容易。通过使用这两个类,你可以轻松地处理异步操作,而不必担心回调或者复杂的线程管理。
  • 响应式编程:Flux和Mono是响应式编程的核心概念。它们允许你以声明性的方式处理数据流,并且能够方便地应对数据流的变化和处理多个并发事件。
  • 组合操作:Flux和Mono提供了丰富的操作符,可以方便地对数据流进行转换、过滤、合并等操作。这些操作符使得对数据流进行复杂的处理变得简单和高效。
  • 异步和并发:Flux和Mono可以很容易地与Java的异步和并发框架集成,比如CompletableFuture和Java 8的CompletableFuture。这使得在异步和并发场景中使用Flux和Mono变得更加方便和灵活。

怎么使用它们呢?

在Java项目中使用Flux和Mono是使用Project Reactor库的常见操作。Project Reactor是一个用于构建基于响应式编程的库,它提供了Flux和Mono两个主要的数据类型,分别用于多个值和单个值的响应式流。

提供一个小示例代码:

演示如何使用各种操作符来处理响应式流
1.首先需要在java中引入依赖

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
    <version>3.4.11</version> 
</dependency>

2.在代码中使用Flux和Mono:

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

public class ECommercePlatform {

    // 模拟从数据库中获取产品列表
    public static Flux<Product> getProductsFromDatabase() {
        List<Product> products = Arrays.asList(
                new Product(1, "Laptop", 1000),
                new Product(2, "Smartphone", 800),
                new Product(3, "Headphones", 200),
                new Product(4, "Tablet", 600)
        );
        return Flux.fromIterable(products);
    }

    // 模拟从外部API获取特价产品信息
    public static Flux<Product> getSpecialOffers() {
        List<Product> specialOffers = Arrays.asList(
                new Product(5, "Smartwatch", 300),
                new Product(6, "Camera", 700)
        );
        return Flux.fromIterable(specialOffers);
    }

    // 模拟从消息队列获取新产品通知
    public static Mono<Product> getNewProductNotification() {
        // 假设我们每次只收到一条新产品通知
        return Mono.just(new Product(7, "Speaker", 150));
    }

    public static void main(String[] args) {
        // 从各个数据源获取产品信息,并合并成一个Flux
        Flux<Product> allProducts = Flux.concat(
                getProductsFromDatabase(),
                getSpecialOffers(),
                getNewProductNotification()
        );

        // 过滤出价格低于500的产品
        Flux<Product> filteredProducts = allProducts.filter(product -> product.getPrice() < 500);

        // 按价格升序排序产品
        Flux<Product> sortedProducts = filteredProducts.sort((p1, p2) -> p1.getPrice() - p2.getPrice());

        // 订阅最终的产品流并处理每个产品
        sortedProducts.subscribe(product -> System.out.println("Product: " + product));
    }

    static class Product {
        private int id;
        private String name;
        private int price;

        public Product(int id, String name, int price) {
            this.id = id;
            this.name = name;
            this.price = price;
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public int getPrice() {
            return price;
        }

        @Override
        public String toString() {
            return "Product{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
}

我们首先从数据库、外部API和消息队列中获取产品信息,然后使用concat操作符将它们合并成一个Flux。然后,我们使用filter操作符过滤出价格低于500的产品,再使用sort操作符按价格升序对产品进行排序。最后,我们订阅最终的产品流,并打印每个产品的信息。

第二问题

其中提到并发和异步,那就来加一个同步异步并发并行的区别吧

  • 同步:指的是任务按照顺序依次执行,一个任务的执行需要等待上一个任务完成后才能开始。在同步操作中,如果一个任务阻塞(比如等待I/O操作完成),则整个线程都会被阻塞,直到任务完成。

如果看不懂举一个例子理解:假设你在食堂排队打饭,每个人依次进行。当你的轮到时,你需要等待前面的人依次打饭完成才能轮到你。这就是同步的典型例子,因为你必须等待前面的任务(其他人打饭)完成后才能执行你自己的任务(打饭)。

  • 异步:指的是任务可以独立执行,不需要等待其他任务完成。在异步操作中,一个任务的执行不会阻塞其他任务的执行,可以继续执行其他任务或者等待任务完成的通知。异步操作通常通过回调函数、Promise、async/await等方式来处理。

例子理解:现在假设食堂引入了预约打饭的系统。你可以提前在手机上预约打饭的时间,并在预约的时间点到达食堂,直接取饭而无需排队等待。这种情况下,你的打饭操作与其他人的打饭操作是独立的,你不需要等待其他人完成打饭,因此是异步的。

  • 并发:指的是多个任务在同一个时间段内交替执行。虽然这些任务可能在同一时刻都在执行,但实际上它们可能会分时执行,通过时间片轮转等方式来实现。
    例子理解:假设食堂只有一条打饭线,但有多个人排队。每个人都在等待自己的食物被准备好,但是厨师可能会交替地为每个人准备食物,因此在某一时刻,多个人都在等待他们的食物,这就是并发。尽管只有一个厨师,但是他可以交替为不同人准备食物,实现了并发操作。
  • 并行:指的是多个任务同时执行,每个任务都在独立的处理器上执行,不会相互干扰。并行可以通过多核处理器、分布式系统等方式来实现。

例子理解:现在假设食堂有多条打饭线,每条线路都有自己的厨师。这样,多个人可以同时打饭,每个人的打饭操作都在独立的线路上进行,彼此互不影响。这就是并行操作,因为多个任务(打饭操作)同时进行,每个任务都在独立的线路上并行执行。
加油伙伴!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱写Bug的小孙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值