Schdulers.elasti c не создает новые темы в Reactor - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь создать поток, в котором поток испускает 10 элементов, каждый параллельно, каждый элемент спит в течение 1 с. Поскольку каждый элемент публикуется в отдельном потоке, я ожидаю, что весь процесс займет 1 с. Но журналы показывают, что вместо этого требуется 10 секунд.

Я попытался изменить подписку на публикацию, сопоставить с doOnNext. Но ни один из них, похоже, не работает.

Я новичок в Reactor и пытаюсь понять, где я иду не так. Любая помощь будет наиболее ценной. Спасибо

    public void whenIsANewThreadCreated() {
        Flux.range(1,10)
                .publishOn(Schedulers.elastic())
                .map(count -> {
                    logger.info(Thread.currentThread().getName() + " - Sleeping for 1s" + " with count: " + count);
                    try {
                        Thread.sleep(1_000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return count;
                })
        .blockLast();
    }
2020-03-30 16:17:29.799  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 1
2020-03-30 16:17:30.802  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 2
2020-03-30 16:17:31.804  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 3
2020-03-30 16:17:32.805  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 4
2020-03-30 16:17:33.806  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 5
2020-03-30 16:17:34.808  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 6
2020-03-30 16:17:35.809  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 7
2020-03-30 16:17:36.811  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 8
2020-03-30 16:17:37.812  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 9
2020-03-30 16:17:38.814  INFO 15744 --- [      elastic-2] com.example.demo.DemoApplicationTests    : elastic-2 - Sleeping for 1s with count: 10

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Спецификация требует, чтобы onNext события вызывались последовательно. Ваш map эффективно превращает входные onNext события в onNext события, которые блокируются на 1 секунду. Согласно спецификации c, 10 входящих onNext приводят к серии из 10 исходящих onNext, которые каждый блок на 1 с => 10 с блокировки.

Вы абсолютно 100% должны использовать parallel(10).runOn(Scheduler.elastic()), если Вы хотите распределить эту блокирующую нагрузку на 10 параллельных направляющих. (Scheduler для runOn также может быть Schedulers.boundedElastic() или Schedulers.newParallel(10)).

1 голос
/ 30 марта 2020

Сначала необходимо создать параллельный поток, вызвав метод parallel, и вы должны использовать runOn для достижения параллелизма.

Flux.range(1,10)
    .parallel()
    .runOn(Schedulers.elastic())
    .map(count -> {
        System.out.println(Thread.currentThread().getName() + " - Sleeping for 1s" + " with count: " + count);
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return count;
    }).subscribe();

  • Использовать Schedulers.boundedElastic() как Scheduler.elastic() не рекомендуется
  • parallel по умолчанию создает потоки на основе ядра вашего процессора. Если вы хотите больше потоков, используйте parallel(10) - я думаю, это то, что вы хотите увидеть.
...