@Dik_Nik

Как избежать впустую расходования ресурсов при чтении из BlockingQueue Java?

Добрый день!
Имеется следующая архитектура сервиса:
640e19f91578f594607511.png
Как видно из рисунка, имеется несколько тредов-продюсеров, которые пишут каждый в свою очередь, и один тред-консьюмер, который читает из всех очередей.
Проблема в том, что консьюмер работает в бесконечном цикле и впустую расходует большое количество процессорного времени и значительное количество памяти, на создание итератора.
Может кто нибудь знает, есть ли возможность засыпать, если очереди пустые и просыпаться, если в очередях что-то появилось, например как это сделано в nio библиотеки с Селектором?
  • Вопрос задан
  • 132 просмотра
Пригласить эксперта
Ответы на вопрос 1
xez
@xez Куратор тега Java
TL Junior Roo
Кажется, вашу проблему полностью решает project reactor

Вот небольшое демо:

@Test
    void testMultiproducer() throws InterruptedException {

        Sinks.Many<Integer> sinksA = Sinks.many().multicast().onBackpressureBuffer();
        Sinks.Many<Integer> sinksB = Sinks.many().multicast().onBackpressureBuffer();
        Sinks.Many<Integer> sinksC = Sinks.many().multicast().onBackpressureBuffer();

        Sinks.Many<Integer> sinkCommon = Sinks.many()
                .multicast()
                .onBackpressureBuffer();

        sinkCommon.asFlux()
                .mergeWith(sinksA.asFlux().delayElements(Duration.ofMillis(100)))
                .mergeWith(sinksB.asFlux().delayElements(Duration.ofMillis(200)))
                .mergeWith(sinksC.asFlux().delayElements(Duration.ofMillis(300)))
                .subscribe(e -> log.info("Element {}", e));  // Your consumer
        
        IntStream.range(0, 100)
                .forEach(sinksA::tryEmitNext);  // Your producers

        IntStream.range(1000, 1100)
                .forEach(sinksB::tryEmitNext);

        IntStream.range(2000, 2100)
                .forEach(sinksC::tryEmitNext);

        Thread.sleep(10000); // Is necessary for test only
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы