Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.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
Java 通量法的公布不';I don’我没有按预期工作_Java_Project Reactor - Fatal编程技术网

Java 通量法的公布不';I don’我没有按预期工作

Java 通量法的公布不';I don’我没有按预期工作,java,project-reactor,Java,Project Reactor,我正试图将阻塞用户集成为反应堆铝-SR1中的通量用户。我想使用一个并行的调度程序来同时执行阻塞操作 我实现了一个主类来描述我的意图: package etienne.peiniau; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import reactor.core.publisher.Flux; import reactor.core.scheduler.Schedulers;

我正试图将阻塞用户集成为反应堆铝-SR1中的通量用户。我想使用一个并行的调度程序来同时执行阻塞操作

我实现了一个主类来描述我的意图:

package etienne.peiniau;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
import reactor.util.function.Tuple2;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Flux.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
                .elapsed()
                .publishOn(Schedulers.parallel())
                .subscribe(new Subscriber<Tuple2<Long, Integer>>() {
                    @Override
                    public void onSubscribe(Subscription subscription) {
                        System.out.println("[" + Thread.currentThread().getName() + "] Subscription");
                        subscription.request(Long.MAX_VALUE);
                    }

                    @Override
                    public void onNext(Tuple2<Long, Integer> t2) {
                        System.out.println("[" + Thread.currentThread().getName() + "] " + t2);
                        try {
                            Thread.sleep(1000); // long operation
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        System.err.println("[" + Thread.currentThread().getName() + "] Error: " + throwable.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        System.out.println("[" + Thread.currentThread().getName() + "] Complete");
                    }
                });
        // Waiting for the program to complete
        System.out.println("[" + Thread.currentThread().getName() + "] Main");
        Thread.sleep(100000);
    }

}
我的问题是,长操作总是在线程parallel-1上执行,并且每1秒执行一次

我曾尝试手动增加并行性或使用弹性调度程序,但结果是一样的


我认为publishOn方法是专门为这个用例设计的。你能告诉我我是否误解了什么吗?

实际上它按预期工作。你可以看到,并行处理的所有值-经过的时间几乎相同,但你总是在同一个线程中接收元素,这样每次等待1秒

我猜在简单的
Flux
中,并行并不意味着更多线程,而是意味着并行工作。例如,如果您运行以下代码:

Flux.fromIterable(IntStream.range(0, 20).boxed().collect(Collectors.toList()))
            .map(i -> {
                System.out.println("map [" + Thread.currentThread().getName() + "] " + i);
                return i;
            })
            .elapsed()
            .publishOn(Schedulers.single())
            .subscribeOn(Schedulers.single())
            .subscribe(t2 -> {
                System.out.println("subscribe [" + Thread.currentThread().getName() + "] " + t2);
            });
您将看到以下结果:

map [single-1] 0
map [single-1] 1
...
subscribe [single-1] [4,0]
subscribe [single-1] [0,1]
...
您可以看到,首先它对所有元素进行
映射
,然后
消费
。如果将
publishOn
更改为
.publishOn(Schedulers.parallel())
您将看到:

map [single-1] 3
subscribe [parallel-1] [5,0]
map [single-1] 4
subscribe [parallel-1] [0,1]
map [single-1] 5
...
现在它在并行线程中同时执行这两个操作。我不确定我对每件事都理解正确

对于并行执行,有特定的
ParallelFlux
。在下面的示例中,所有操作都将在不同的线程上完成:

Flux.fromIterable(IntStream.range(0, 20).boxed().collect(Collectors.toList()))
        .elapsed()
        .parallel()
        .runOn(Schedulers.parallel())
        .subscribe(t2 -> {
            System.out.println("[" + Thread.currentThread().getName() + "] " + t2);
            try {
                Thread.sleep(1000); // long operation
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, throwable -> {
            System.err.println("[" + Thread.currentThread().getName() + "] Error: " + throwable.getMessage());
        }, () -> {
            System.out.println("[" + Thread.currentThread().getName() + "] Complete");
        }, subscription -> {
            System.out.println("[" + Thread.currentThread().getName() + "] Subscription");
            subscription.request(Long.MAX_VALUE);
        });
结果如下所示:

[parallel-1] [8,0]
[parallel-2] [0,1]
[parallel-3] [0,2]
[parallel-4] [0,3]
[parallel-1] [0,4]
...
因此,它使用很少的线程来处理结果。在我看来,这是非常相似的


还要注意的是,如果使用方法
.subscribe(Subscriber),实际上它可以按预期工作,您可以看到并行处理的所有值-经过的时间几乎相同,但您总是在同一线程内接收元素,并且每次等待1秒都是这样

我猜在simple
Flux
中,并行并不意味着更多线程,而是意味着并行工作

Flux.fromIterable(IntStream.range(0, 20).boxed().collect(Collectors.toList()))
            .map(i -> {
                System.out.println("map [" + Thread.currentThread().getName() + "] " + i);
                return i;
            })
            .elapsed()
            .publishOn(Schedulers.single())
            .subscribeOn(Schedulers.single())
            .subscribe(t2 -> {
                System.out.println("subscribe [" + Thread.currentThread().getName() + "] " + t2);
            });
您将看到以下结果:

map [single-1] 0
map [single-1] 1
...
subscribe [single-1] [4,0]
subscribe [single-1] [0,1]
...
您可以看到,它首先对所有元素进行
映射
,然后
消费
。如果将
publishOn
更改为
。publishOn(Schedulers.parallel())
,您将看到:

map [single-1] 3
subscribe [parallel-1] [5,0]
map [single-1] 4
subscribe [parallel-1] [0,1]
map [single-1] 5
...
现在它在并行线程中同时执行这两个操作。我不确定我是否正确理解了所有内容

并行执行有特定的
ParallelFlux
。在下面的示例中,所有操作都将在不同的线程上完成:

Flux.fromIterable(IntStream.range(0, 20).boxed().collect(Collectors.toList()))
        .elapsed()
        .parallel()
        .runOn(Schedulers.parallel())
        .subscribe(t2 -> {
            System.out.println("[" + Thread.currentThread().getName() + "] " + t2);
            try {
                Thread.sleep(1000); // long operation
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, throwable -> {
            System.err.println("[" + Thread.currentThread().getName() + "] Error: " + throwable.getMessage());
        }, () -> {
            System.out.println("[" + Thread.currentThread().getName() + "] Complete");
        }, subscription -> {
            System.out.println("[" + Thread.currentThread().getName() + "] Subscription");
            subscription.request(Long.MAX_VALUE);
        });
结果如下所示:

[parallel-1] [8,0]
[parallel-2] [0,1]
[parallel-3] [0,2]
[parallel-4] [0,3]
[parallel-1] [0,4]
...
因此,它使用很少的线程来处理结果。在我看来,它确实是并行的


还请注意,如果使用方法
,请订阅(Subscriber@etiennepeiniau我猜在simple Flux中不是“并行==更多线程”。我将编辑我的答案并添加一个示例。@etiennepeiniau我猜在simple Flux中不是“并行==更多线程”。我将编辑我的答案并添加一个示例。