1. Flux.just到底是冷的还是热的?
1. 如果从Flux.just在没有subscribe的时候,就获取数据这点来看,并不能说明属于热的!!!
因为热流是某种情况下被触发,可以是因为在assembly的时候就触发也可以其他情况下甚至是被subscribe的时候被触发。所以触发时间不能作为冷热的区分标志
例如:
Flux<Long> x = Flux.just(System.currentTimeMillis()/1000); System.out.println(System.currentTimeMillis()/1000); Thread.sleep(Duration.ofSeconds(2)); System.out.println(System.currentTimeMillis()/1000); x.subscribe(System.out::println); Thread.sleep(Duration.ofSeconds(2)); x.subscribe(System.out::println); Thread.sleep(1000*3400);
结果:
1735698204
1735698206
1735698204
1735698204
1735698204结果说明在没有subscribe的时候,数据已经写入到了flux中
2. 但是从第二次 x.subscribe(System.out::println);依然可以订阅到数据。说明flux是冷流。
这里就有矛盾
3. 同样可以验证Flux.interval
Flux<Long> x = Flux.interval(Duration.ofMillis(1000))/*.share()*/; Thread.sleep(Duration.ofSeconds(2)); x.subscribe(x1->System.out.println("sb1:"+x1.toString())); Thread.sleep(Duration.ofSeconds(2)); x.subscribe(x1->System.out.println("sb2:"+x1.toString())); Thread.sleep(1000*3400);
结果:
sb1:0
sb1:1
sb1:2
sb2:0
sb1:3
sb2:1
sb2的订阅依然可以从0开始,说明这个Flux.interval是个冷数据
同时:
Flux<Long> x = Flux.interval(Duration.ofMillis(1000)).share(); Thread.sleep(Duration.ofSeconds(2)); x.subscribe(x1->System.out.println("sb1:"+x1.toString())); Thread.sleep(Duration.ofSeconds(2)); x.subscribe(x1->System.out.println("sb2:"+x1.toString())); Thread.sleep(1000*3400);
结果:
sb1:0
sb1:1
sb1:2
sb2:2
sb1:3
sb2:3
sb2只接收到新数据,结合share的功能是将冷数据切换成热数据,似乎也证明了这里Flux.interval是冷数据。
4. 本质原因是冷数据和热数据的定义有问题:
冷数据:
1. They generate data anew for each subscription. If no subscription is created, data never gets generated.
2. 冷数据在被订阅时是从头开始全量发送给subscriber的
热数据:
1. It directly captures the value at assembly time and replays it to anybody subscribing to it later.Hot publishers, on the other hand, do not depend on any number of subscribers.在装配时候就执行,和订阅无关
2. 热数据是从订阅开始后的数据下发
这就导致:
Flux.just是被订阅时是从头开始全量发送给subscriber的。符合冷流特性
所以导致Flux.just流的定义会有矛盾的地方,本质原因是冷/热流包含两种特性。这两种特性其实并不是一定同时存在的。
我的解释就是
因为热流是某种情况下被触发,可以是因为在assembly的时候就触发也可以其他情况下甚至是被subscribe的时候被触发。所以触发时间不能作为冷热的区分标志