Project Reactor Scheduler无法按预期运行

时间:2018-06-25 14:47:13

标签: java multithreading

我正在尝试使用适当的Scheduler获取在不同线程中发射对象的Flux,但它无法按预期工作。订阅Flux时,它将为Flux中的所有元素重复调用onNext()。我希望onNext()在不同的线程中被调用。我已经编写了以下代码来测试期望多线程发生的配置。

package pack;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;

public class TestDelayedOnNext {
    public static void main(String[] args) {
        System.out.println(Schedulers.DEFAULT_POOL_SIZE);
        System.out.println("Tread ID " + Thread.currentThread().getId());
        Flux<String> flux1 = Flux.just("AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF");
        Flux<String> flux2 = flux1.publishOn(Schedulers.newParallel("newParallel"));
        flux2.subscribe(new SampleSubscriber());
    }
}

在每次调用onNext()时,SampleSubscriber将休眠一秒钟,打印提供的字符串和线程ID,然后返回。

package pack;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

public class SampleSubscriber implements Subscriber<String> {
    public void onNext(String str) {
        try {
            Thread.sleep(1000);
            System.out.println(str);
            System.out.println("Tread ID " + Thread.currentThread().getId());
        }
        catch (Exception e) {
        }
    }
    public void onError(Throwable thr) {
        System.out.println(thr);
    }
    public void onComplete() {
        System.out.println("COMPLETED !");
    }
    public void onSubscribe(Subscription subscription) {
        subscription.request(1000);
    }
}

此代码的结果是,原始Flux的所有六个字符串在每个字符串之间打印都具有一秒钟的延迟,并且都在同一线程中。使用明确指定的并行调度程序的flux2构造不会在单独的线程中发出,而只会在一个相同的线程中发出。如果用六个不同的线程调用onNext(),我也希望只有一秒钟的延迟,此后所有六个字符串将在一个突发中打印。但是,这不会发生。为什么不?在单独的线程中进行onNext()调用需要做什么?

这个实际问题背后还有一个理论上的问题。 Reactive Streams API旨在提供“反压”解决方案。该规范提供了向上游传达排放限制的方法。使用Subscription.request(N),可以从上游请求下一个N排放。但是,这仅在Flux可能在单独的线程中向用户充斥排放的情况下才是必需的,因为onNext()的阻塞是一种非常明显的向上游通信的方式,即用户在传输速度方面存在问题。发布者。

在我看来,“无功流”规范解决了背压问题,该问题仅在以下情况下才存在:来自通量的排放可以在单独的线程中完成。因此,造成在单独的线程中完成排放的情况并非易事。

0 个答案:

没有答案