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等方式来处理。
例子
理解:现在假设食堂引入了预约打饭的系统。你可以提前在手机上预约打饭的时间,并在预约的时间点到达食堂,直接取饭而无需排队等待。这种情况下,你的打饭操作与其他人的打饭操作是独立的,你不需要等待其他人完成打饭,因此是异步的。
并发
:指的是多个任务在同一个时间段内交替执行。虽然这些任务可能在同一时刻都在执行,但实际上它们可能会分时执行,通过时间片轮转等方式来实现。
例子
理解:假设食堂只有一条打饭线,但有多个人排队。每个人都在等待自己的食物被准备好,但是厨师可能会交替地为每个人准备食物,因此在某一时刻,多个人都在等待他们的食物,这就是并发。尽管只有一个厨师,但是他可以交替为不同人准备食物,实现了并发操作。并行
:指的是多个任务同时执行,每个任务都在独立的处理器上执行,不会相互干扰。并行可以通过多核处理器、分布式系统等方式来实现。
例子
理解:现在假设食堂有多条打饭线,每条线路都有自己的厨师。这样,多个人可以同时打饭,每个人的打饭操作都在独立的线路上进行,彼此互不影响。这就是并行操作,因为多个任务(打饭操作)同时进行,每个任务都在独立的线路上并行执行。
加油伙伴!!!