繁体   English   中英

助焊剂 stream after.map() function 不按顺序排列

[英]Flux stream after .map() function not in order

在尝试熟悉 Flux 时,我想在 Flux 中有一个 stream 数据。

.map() function 应该模拟一个工作负载,每个Magician object 需要一些随机处理时间,并且发生在不同的线程中(如您在Thread id的 Z78E6221F6393D1356681DB398F14CED6

最后 stream 应该按顺序返回结果。 但无论我做什么,例如使用.sequential() ,或者它总是以无序结束。

有人可以告诉我如何使用多线程(使用.map()或任何其他序列,只要结果是所要求的)并按顺序排列结果? 谢谢

PS 这个问题背后的业务逻辑是我正在调用一个提供Flux<byte[]>的端点

我需要并行处理这些字节(解密)并因此转发给另一个消费者。

public class FluxRunner {

    public void getWorkerStream() throws InterruptedException {
        final int[] counter = new int[1];

        // create workers
        final Flux<Magician[]> workersFlux = Flux.range(0, 10)
                .map(integer -> {
                    final Magician[] worker = new Magician[1];
                    worker[0] = new Magician(counter[0], counter[0]++);
                    return worker;
                });

        final Disposable disposable = workersFlux
                .parallel()
                .runOn(Schedulers.parallel())
                .map(workers -> {
                    System.out.println("Thread id: " + Thread.currentThread().getId());
                    workers[0].calculate();
                    return workers;
                })
                .sequential() // no effect, doOnNext is unordered
                .doOnNext(workers -> System.out.println(workers[0].getId()))
                .subscribe();

        while (!disposable.isDisposed()) {
            sleep(500);
        }
    }
}

@Data
class Magician {

    final int id;
    int number;

    Magician(final int id, final int number) {
        this.id = id;
        this.number = number;
    }

    public void calculate() {
        int timeToSleep = (int) (Math.random() * 3000);
        System.out.println("Sleep for " + timeToSleep + " seconds");
        try {
            sleep(timeToSleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        number++;
    }
}

结果将是

Thread id: 33
Thread id: 24
Thread id: 25
Thread id: 31
Thread id: 29
Thread id: 30
Thread id: 27
Thread id: 32
Thread id: 28
Thread id: 26
Sleep for 2861 seconds
Sleep for 2811 seconds
Sleep for 711 seconds
Sleep for 2462 seconds
Sleep for 1858 seconds
Sleep for 601 seconds
Sleep for 126 seconds
Sleep for 359 seconds
Sleep for 2014 seconds
Sleep for 2356 seconds
4
5
7
9
8
3
0
1
6
2

您可以使用flatMapSequential运算符和.subscribeOn(Schedulers.parallel())来获得所需的结果:

final Disposable disposable = workersFlux
    .flatMapSequential(workers -> Mono.fromCallable(() -> {
        System.out.println("Thread id: " + Thread.currentThread().getId());
        workers[0].calculate();
        return workers;
    }).subscribeOn(Schedulers.parallel()))
    .doOnNext(workers -> System.out.println(workers[0].getId()))
    .subscribe();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM