Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 订阅UnicastProcessor从不触发_Spring_Project Reactor - Fatal编程技术网

Spring 订阅UnicastProcessor从不触发

Spring 订阅UnicastProcessor从不触发,spring,project-reactor,Spring,Project Reactor,我希望在项目出现时对其进行批处理,因此我创建了一个UnicastProcessor,并像这样订阅了它 UnicastProcessor<String> processor = UnicastProcessor.create() processor .bufferTimeout(10, Duration.ofMillis(500)) .subscribe(new Subscriber<List<String>>() {

我希望在项目出现时对其进行批处理,因此我创建了一个UnicastProcessor,并像这样订阅了它

UnicastProcessor<String> processor = UnicastProcessor.create()

processor
        .bufferTimeout(10, Duration.ofMillis(500))
        .subscribe(new Subscriber<List<String>>() {
            @Override
            public void onSubscribe(Subscription subscription) {
                System.out.println("OnSubscribe");
            }

            @Override
            public void onNext(List<String> strings) {
                System.out.println("OnNext");
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println("OnError");
            }

            @Override
            public void onComplete() {
                System.out.println("OnComplete");
            }
        });
UnicastProcessor=UnicastProcessor.create()
处理器
.bufferTimeout(10,持续时间.百万(500))
.subscribe(新订户(){
@凌驾
认购时的公共作废(认购){
System.out.println(“OnSubscribe”);
}
@凌驾
public void onNext(列出字符串){
System.out.println(“OnNext”);
}
@凌驾
公共作废登记员(可丢弃){
System.out.println(“OnError”);
}
@凌驾
未完成的公共空间(){
System.out.println(“OnComplete”);
}
});
然后出于测试目的,我创建了一个新线程,并开始在循环中添加项

new Thread(() -> {
    int limit = 100
    i = 0
    while(i < limit) {
        ++i
        processor.sink().next("Hello $i")
    }
    System.out.println("Published all")
}).start()
新线程(()->{
整数极限=100
i=0
while(i
运行此操作(并让主线程休眠5秒钟)后,我可以看到所有项目都已发布,但订阅者不会触发任何事件,因此我无法处理任何已发布的项目

我做错了什么?

反应流规范就是答案! 发布者向订阅者发送的onNext的总数 必须小于或等于请求的元素总数 由该认购人随时认购

在您的示例中,您只需提供一个在任何意义上都不做任何事情的订阅者。反过来,reactivestreams规范直接指出,如果您没有调用
Subscription#request
方法,则不会发生任何事情(不会有onNext调用)

订阅者必须通过Subscription.request(长n)向用户发出请求信号 接收下一个信号

因此,要解决您的问题,可能的解决方案之一是以以下方式更改代码:

UnicastProcessor<String> processor = UnicastProcessor.create()

processor
    .bufferTimeout(10, Duration.ofMillis(500))
    .subscribe(new Subscriber<List<String>>() {
        @Override
        public void onSubscribe(Subscription subscription) {
            System.out.println("OnSubscribe");
            subscription.request(Long.MAX_VALUE);
        }

        @Override
        public void onNext(List<String> strings) {
            System.out.println("OnNext");
        }

        @Override
        public void onError(Throwable throwable) {
            System.out.println("OnError");
        }

        @Override
        public void onComplete() {
            System.out.println("OnComplete");
        }
    });

注意,在本例中,我执行了另一个方法
serialize
,该方法提供线程安全接收器,并确保同时调用
FluxSink#next
不会导致违反ReactiveStreams规范。

另一个问题:您还应该调用
sink()
仅一次,并重用提供的
FluxSink
而不是在循环中调用它。@SimonBaslé,从技术上讲,这是可能的,因为
UnicastProcessor
在默认队列的情况下提供内部同步,但是是的。我会提到
UnicastProcessor<String> processor = UnicastProcessor.create()
FluxSink<String> sink = processor.serialize().sink();
...
new Thread(() -> {
    int limit = 100
    i = 0
    while(i < limit) {
        ++i
        sink.next("Hello $i")
    }
    System.out.println("Published all")
}).start()