响应式编程
文章平均质量分 56
qian_348840260
这个作者很懒,什么都没留下…
展开
-
Reactor3 源码解析二十八:总结
Reactive Stream Specification链式编程实现Reactor线程调度JCTools使用函数式编程原子变量AtomicReference单例模式(11)滑动窗口(18)原创 2021-01-15 22:38:53 · 276 阅读 · 0 评论 -
Reactor3 功能介绍二十七: 测试&调试
Reactor的调试功能还是蛮强大的,log("xxxxxxxxxxx")可以打印出数据上下游传递的信息。参考文档:Project Reactor学习(6)--测试Reactor的调试——响应式Spring的道法术器反应式编程(Reactive Programming)...原创 2021-01-15 18:44:42 · 952 阅读 · 0 评论 -
Reactor3 功能介绍二十六: Context
在响应式编程中,一个线程很可能被用于处理多个异步订阅关系, 同样,一个订阅关系在元素下发的过程中往往可能从一个线程切换到另一个线程。那么上下文变量如何传播呢?首先来看一个Context的简单用法: //案例一 String key = "message"; Mono.subscriberContext() .map( ctx -> "Hello " + ctx.get(key)) .subscriberContext( ctx -> ct原创 2021-01-15 16:22:12 · 2499 阅读 · 0 评论 -
Reactor3 功能介绍二十五: ConnectableFlux
Flux<Long> flux = Flux.interval(Duration.ofMillis(50), Duration.ofMillis(100)) .take(5) .doOnSubscribe(s -> System.out.println("subscribed to source")); flux.subscribe(x -> { System.out.println("____" + x); }); Threa...原创 2021-01-14 18:27:52 · 718 阅读 · 0 评论 -
Reactor3 功能介绍二十四: combineLatest操作
combineLatest操作会把所有源中最新产生的元素合并成一个新元素下发。只要其中任何一个源中产生了新元素,合并操作就会执行一次,然后下发新产生的元素。如下图所示:Demo: Flux.combineLatest( Flux.interval(Duration.ofMillis(50), Duration.ofMillis(100)).map(x -> "a"+x).take(5), Flux.interval(Duration.Z.原创 2021-01-14 16:11:24 · 651 阅读 · 0 评论 -
Reactor3 源码解析二十三: FluxConcatMap源码剖析
Flux.just(5, 10) .concatMap(x -> Flux.interval(Duration.ofMillis(x * 10), Duration.ofMillis(100)).take(x)) .subscribe(System.out::println); Thread.sleep(1000*60l);concatMap操作与flatMapSequential操作非常相似,但在底层实现上有区别。flatMapSequential是...原创 2021-01-14 15:26:58 · 887 阅读 · 0 评论 -
Reactor3 源码解析二十二: FluxFlatMap源码剖析
flatMap 和 flatMapSequential 操作符把流中的每个元素转换成一个流,再把所有流中的元素进行合并。flatMapSequential 和 flatMap 之间的区别与 mergeSequential 和 merge 之间的区别是一样的。 Flux.just(5, 10) .flatMap(x -> Flux.interval(Duration.ofMillis(x * 10), Duration.ofMillis(100)).take(x))原创 2021-01-14 10:52:26 · 929 阅读 · 0 评论 -
Reactor3 源码解析二十一: FluxMerge源码剖析
前面二十章节主要以源码剖析为主,着重讲解reactor的调用流程,productor、consumer、subscription三者如何协调工作。reactor设计思路基本是一致,后面将着重功能介绍,感兴趣可以自行追踪源码(具备了前20章节的源码分析能力,针对新的API进行剖析并非难事)。Flux的buffer、window、groupBy主要是针对源序列进行拆分,将元素分配到不同的容器或group中,进行批处理。而merge和mergeSequential操作是将多个源合并成一个Flux源。merge原创 2021-01-13 15:35:11 · 1088 阅读 · 0 评论 -
Reactor3 源码解析二十: FluxGroupBy源码剖析
Flux.just(1, 3, 5, 2, 4, 6, 11, 12, 13) .groupBy(i -> i % 2 == 0 ? "even" : "odd") .subscribe(f -> f.subscribe(t->System.out.println(f.key() + " : " + t)));输出结果:odd : 1odd : 3odd : 5even : 2even : 4even : 6odd ...原创 2021-01-13 13:58:19 · 1143 阅读 · 0 评论 -
Reactor3 源码解析十九: FluxWindow源码剖析
public static void main(String[] args) throws Exception{ Flux.range(1, 40).window(20).subscribe(f -> f.subscribe(System.out::print)); System.out.println("############"); Flux.range(1, 4).windowUntil(i -> i % 2 == 0).subscrib..原创 2021-01-13 11:18:58 · 588 阅读 · 0 评论 -
Reactor3 源码解析十八: FluxBuffer源码剖析(2)
数据源源不断涌来,需要每隔15秒做一次统计,统计近1min的指标数据。Reactor给出了可能最优雅、最简洁的实现。 Flux.interval(Duration.ofSeconds(1)).buffer(Duration.ofSeconds(60),Duration.ofSeconds(15)).subscribe(System.out::println); Thread.sleep(180*1000l);Flux.interval(Duration.ofSeconds(1)) 模...原创 2021-01-12 18:32:27 · 602 阅读 · 0 评论 -
Reactor3 源码解析十七: FluxBuffer源码剖析(1)
buffer操作主要将源生产的元素进行打包,然后交由后续的中间操作或消费者处理,有点类似于批处理。 Flux.range(1, 100).buffer(20).subscribe(System.out::println); //一直收集元素,直到Predicate返回true,开启下一次收集 Flux.range(1, 10).bufferUntil(i -> i%3 == 0).subscribe(System.out::println); //只收集Predicate为true原创 2021-01-11 18:38:57 · 604 阅读 · 0 评论 -
Reactor3 源码解析十六: Flux.transform & Flux.compose源码剖析
Flux可以组合多个中间操作,增加代码的复用性及简洁度。Flux.tranform 示例Function<Flux<String>, Flux<String>> filterAndMap = f -> f.filter(color ->!color.equals("orange")) .map(String :: toUpperCase); Flux.fromIterable(Arrays.asList("blue","green","o原创 2021-01-11 14:38:53 · 3028 阅读 · 0 评论 -
Reactor3 源码解析十五: ParllelFlux源码剖析
Flux.range(1,10) .parallel() .runOn(Schedulers.parallel()) .subscribe(x ->{ System.out.println(Thread.currentThread().getName() + " : " + x); }); Thread.sleep(20l);执行结果:parallel-1 : 1p...原创 2021-01-08 10:54:38 · 515 阅读 · 0 评论 -
Reactor3 源码解析十四: ParallelScheduler源码剖析
公司预计要成立派单组,成立之初已经预估了HC,即不管多少活,就这些人力,不管你手头有没有活,来新活就轮询安排,领导偶尔想找个人单独部署点活儿,轮到你了,算你'幸运',原来的活还要干,新安排的活儿是白加的小菜,所有的活还是按照正常的调度来完成,领导新加的小菜也不例外(不加塞)。ParallelScheduler的实现和ElasticScheduler非常类似,底层都是使用单线程的ScheduledThreadPoolExecutor来调度任务,不同的是ElasticScheduler下面的员工人数(Sch原创 2021-01-07 10:59:10 · 292 阅读 · 1 评论 -
Reactor3 源码解析十三: ElasticScheduler源码剖析(2)
在Reactor3 源码解析十二: ElasticScheduler源码剖析(1)中主要讲解了,向派单组提交一个任务,派单组内部调度处理。使用方式如下: public static void main(String[] args) throws Exception{ Scheduler s = Schedulers.elastic(); s.schedule(() -> { System.out.println(Thread.currentThread().getName() +原创 2021-01-06 17:32:55 · 372 阅读 · 0 评论 -
Reactor3 源码解析十二: ElasticScheduler源码剖析(1)
公司成立派单组,来完成派单类需求任务。刚开始派单组没有人员,新任务到来,招聘人员A来完成。突然又来了一个新任务,发现派单组唯一的小伙伴A还在处理手头的活儿,于是再招聘一个小伙伴B,来完成新提交的任务。A和B先后完成了自己的任务后,这时候第三个任务来了,发现有空闲状态的小伙伴A和B,于是让A接受新任务。第四个任务持续没有到来,B伙伴一直处于闲置状态,公司为节省成本于是解雇了B。刚解雇B,第四个任务就来了,A抽不出身,于是只能重新招聘C来完成新任务。周而复始,员工和任务都是进进出出。 ...原创 2021-01-06 15:06:44 · 352 阅读 · 1 评论 -
Reactor3 源码解析十一: Schedulers之单例模式
单例模式一般有两种实现方式: 静态内部类 和 DCL+volatilereactor的Schedulers另辟新境,使用AtomicReference变相实现单例模式。 public static Scheduler elastic() { return cache(CACHED_ELASTIC, ELASTIC, ELASTIC_SUPPLIER); } static AtomicReference<CachedScheduler> CACHED_ELASTIC原创 2021-01-05 16:55:03 · 454 阅读 · 0 评论 -
Reactor3 源码解析十: FluxHandle源码剖析
public class FluxHandleMain { public static void main(String[] args) { Flux<String> alphabet = Flux.just(-3, 40, 18, 9, 20) .handle((i, sink) -> { String letter = alphabet(i); if .原创 2021-01-05 15:21:05 · 305 阅读 · 0 评论 -
Reactor3 源码解析九: Flux.push PK Flux.create
Flux.push(sink -> { // 向下游发布元素 for (int i = 0; i <= 100; i++) { System.out.println("create: " + Thread.currentThread().getName() + " " + i); sink.next(i); } // 结束发布元素 sink.complete(); }) .subscribe(s -> System.out.p...原创 2021-01-05 11:17:04 · 999 阅读 · 0 评论 -
Reactor3 源码解析八: FluxSubscribeOn源码剖析
Flux.just("tom", "jack", "allen") .filter(s -> s.length() > 3) .doOnNext(s -> { System.out.println("producter: " + Thread.currentThread().getName() + " " + s); }) .subscribeOn(Schedulers.parallel()) ...原创 2021-01-04 16:16:39 · 1043 阅读 · 1 评论 -
Reactor3 源码解析七: FluxPublishOn源码剖析(2)
Flux.create(emitter -> { for (int i = 0; i <= 20; i++) { if (emitter.isCancelled()) { return; } System.out.println(Thread.currentThread().getName() + ":Source created " + i); emitter.next(i); } }).doOnNext(s -...原创 2021-01-02 23:15:38 · 586 阅读 · 0 评论 -
Reactor3 源码解析六: FluxPublishOn源码剖析(1)
Flux.create(emitter -> { for (int i = 0; i <= 5; i++) { if (emitter.isCancelled()) { return; } System.out.println(Thread.currentThread().getName() + ":Source created " + i); emitter.next(i); } }).doOnNext(s -&...原创 2020-12-31 10:23:13 · 768 阅读 · 1 评论 -
Reactor3 源码解析五: FluxGenerate源码剖析
Flux.generate((synchronousSink) -> { synchronousSink.next(1); //不支持多个next操作 //synchronousSink.next(2); }) .subscribe(System.out::println);执行结果: System.out.println(1)被执行无数次原创 2020-12-30 16:00:55 · 702 阅读 · 0 评论 -
Reactor3 源码解析四: FluxCreate源码剖析
FluxCreate与FluxArray一样implements SourceProducer,都是最底层的生产者(非中间层)。与FluxArray最明显的不同是,FluxCreate实现背压backpressure的功能(背压是响应式编程的一个亮点)。调用方式 Flux.create(sink -> { //向下游发布元素 for (int i = 0; i <= 100; i++) { sink.next(i);原创 2020-12-30 11:21:40 · 1158 阅读 · 1 评论 -
Reactor3 源码解析三: FluxPeek源码剖析
FluxPeek是一个中间操作,peek译义为"偷窥",简单的理解就是对上下游的onSubscribe,onNext,onError,onComplete,request等进行增强操作,类似实现了spring aop的功能。Flux.just("tom", "jack", "allen") .filter(s -> s.length() > 3) .map(s -> s.concat("@qq.com")) .doOnNext(s -> { ...原创 2020-12-30 10:47:31 · 606 阅读 · 1 评论 -
Reactor3 源码解析二: 一个简单的例子(2)
Flux.just("tom", "jack", "allen") .filter(s -> s.length() > 3) .map(s -> s.concat("@qq.com")) .subscribe(System.out::println);上篇文章主要针对此代码的源码全程跟踪了一遍,下面将对整个调用(主过程)进行一个总结:生产者链式构建1.FluxArray2. FluxFilter(FluxArray)3. Fl...原创 2020-12-29 17:32:43 · 494 阅读 · 1 评论 -
Reactor3 源码解析一: 一个简单的例子(1)
拆解源码之前,可以先参阅入门文章Project Reactor 核心原理解析及Reactive响应式流入门。实例: Flux.just("tom", "jack", "allen") .filter(s -> s.length() > 3) .map(s -> s.concat("@qq.com")) .subscribe(System.out::println);1. 通过静态方法Flux.just生成一个FluxArray对象...原创 2020-12-29 14:19:43 · 997 阅读 · 0 评论 -
响应式编程学习指南
1. 响应式编程入门JDK历史版本对响应式编程的支持。jdk8中,已经出现了一些响应式编程的影子(CompletableFuture&Stream)。jdk9通过java.util.concurrent.Flow包,提供了对于 Reactive 的完整支持。Reactive响应式流入门这篇文章基于jdk9给出了一个"hello world"级别的例子,给初学者一个初式的印象。2. 进一步了解响应式编程spring5及spring boot2开启了对响应式编程的支持,这两个版本基于jdk8原创 2020-11-13 14:01:29 · 498 阅读 · 0 评论 -
Project Reactor 深度解析
现在, Java 的各种基于 Reactor 模型的响应式编程库或者框架越来越多了,像是 RxJava,Project Reactor,Vert.x 等等等等。在 Java 9, Java 也引入了自己的 响应式编程的一种标准接口,即java.util.concurrent.Flow这个类。这个类里面规定了 Java 响应式编程所要实现的接口与抽象。我们这个系列要讨论的就是Project Reactor这个实现。这里也提一下,为了能对于没有升级到 Java 9 的用户也能兼容,java.util.con转载 2020-11-13 11:43:56 · 2987 阅读 · 0 评论 -
Project Reactor 核心原理解析
一、开篇本文将解析 Spring 的 Reactor 项目的源码。主要目的是让自己能深入理解 Reactor 这个项目,以及 Spring 5 和 Spring Boot 2。Project Reactor 项目地址:https://github.com/reactorReactor 项目主要包含 Reactor Core 和 Reactor Netty 两部分。Reactor Core 实现了反应式编程的核心功能,Reactor Netty 则是 Spring WebFlux 等技术的基础。本转载 2020-11-12 11:01:18 · 1994 阅读 · 0 评论 -
Reactive响应式流入门
再谈响应式在前一篇文章 从Reactive编程到“好莱坞” 中,谈到了响应式的一些概念,讲的有些发散。但仅仅还是停留在概念的层面,对于实战性的东西并没有涉及。所以大家看了后,或许还是有些不痛不痒。响应式编程强调的是异步化、面向流的处理方式,这两者也并非凭空生出,而是从大量的技术实践中总结提炼出来的概念,就比如:我们谈异步化,容易联想到 Java 异步IO(Asynchronized IO),而且习惯于将其和 BIO、NIO等概念来做对比。殊不知,老早出现的 Swing 框架(Java UI)就已转载 2020-11-04 14:53:45 · 1119 阅读 · 0 评论