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) {// 从各个数据源获取产品信息,并合并成一个FluxFlux<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;}@Overridepublic String toString() {return "Product{" +"id=" + id +", name='" + name + '\'' +", price=" + price +'}';}}
}
我们首先从数据库、外部API和消息队列中获取产品信息,然后使用concat操作符将它们合并成一个Flux。然后,我们使用filter操作符过滤出价格低于500的产品,再使用sort操作符按价格升序对产品进行排序。最后,我们订阅最终的产品流,并打印每个产品的信息。
第二问题
其中提到并发和异步,那就来加一个同步
和异步
,并发
和并行
的区别吧
同步
:指的是任务按照顺序依次执行,一个任务的执行需要等待上一个任务完成后才能开始。在同步操作中,如果一个任务阻塞(比如等待I/O操作完成),则整个线程都会被阻塞,直到任务完成。
如果看不懂举一个例子
理解:假设你在食堂排队打饭,每个人依次进行。当你的轮到时,你需要等待前面的人依次打饭完成才能轮到你。这就是同步的典型例子,因为你必须等待前面的任务(其他人打饭)完成后才能执行你自己的任务(打饭)。
异步
:指的是任务可以独立执行,不需要等待其他任务完成。在异步操作中,一个任务的执行不会阻塞其他任务的执行,可以继续执行其他任务或者等待任务完成的通知。异步操作通常通过回调函数、Promise、async/await等方式来处理。
例子
理解:现在假设食堂引入了预约打饭的系统。你可以提前在手机上预约打饭的时间,并在预约的时间点到达食堂,直接取饭而无需排队等待。这种情况下,你的打饭操作与其他人的打饭操作是独立的,你不需要等待其他人完成打饭,因此是异步的。
并发
:指的是多个任务在同一个时间段内交替执行。虽然这些任务可能在同一时刻都在执行,但实际上它们可能会分时执行,通过时间片轮转等方式来实现。
例子
理解:假设食堂只有一条打饭线,但有多个人排队。每个人都在等待自己的食物被准备好,但是厨师可能会交替地为每个人准备食物,因此在某一时刻,多个人都在等待他们的食物,这就是并发。尽管只有一个厨师,但是他可以交替为不同人准备食物,实现了并发操作。并行
:指的是多个任务同时执行,每个任务都在独立的处理器上执行,不会相互干扰。并行可以通过多核处理器、分布式系统等方式来实现。
例子
理解:现在假设食堂有多条打饭线,每条线路都有自己的厨师。这样,多个人可以同时打饭,每个人的打饭操作都在独立的线路上进行,彼此互不影响。这就是并行操作,因为多个任务(打饭操作)同时进行,每个任务都在独立的线路上并行执行。
加油伙伴!!!