Как создать параллельную очередь Java, из которой мы можем заблокировать более одного элемента за один вызов?

1

Предпосылки: Мне нужно отправить несколько сообщений небольшого размера клиентам WebSocket асинхронным способом. Сообщения обычно отправляются в пике, поэтому после некоторой паузы мне нужно быстро отправить ~ 5000 сообщений. Таким образом, проблема заключается в следующем:

  • Я не хочу запускать 5000 асинхронных потоков в одном потоке
  • Я не хочу зацикливать "start async" - "дождаться завершения" 5000 раз в серийном
  • Я не хочу использовать 5000 потоков, с одиночным "start async" - "ждать полного" на поток

Лучшим способом было бы группировать ~ 20 асинхронных потоков, поэтому мне нужна очень конкретная очередь:

  • много способов одновременного push/poll в очереди
  • малые асинхронные средства. Я хочу опросить пучки, например от 1 до 20 сообщений в строке take() (чтобы я мог запускать 1... 20 async I/O и ждать завершения в одном потоке)
  • немедленно означает, что я не хочу ждать, пока будет опрошено 20 сообщений, пакетный опрос должен использоваться только в том случае, если в очереди много сообщений. Одно сообщение должно быть опрошено и отправлено немедленно.

Итак, в основном: мне нужна структура, подобная очереди, которая блокирует элементы ожидания (от 1 до X) в одном блокирующем вызове. псевдокод:

[each of ~50 processing threads]:
messages = queue.blockingTake( max 10 or at least 1 if less than 10 available );
for each message: message.startAsync()
for each message: message.waitToComplete()
repeat
Теги:
websocket
concurrency
queue
producer-consumer

1 ответ

0

Я бы не реализовал Очередь с нуля, если это действительно не нужно. Несколько идей, если вам интересно:

Queue> если у вас есть только 1 поток, делающий предложения. Если у вас больше, коллекция должна быть синхронизирована. Например, один вызывающий peek() -s в очередь, видит, что в последней коллекции слишком много элементов, поэтому она создает новую и предлагает ее.

или

Ряд бегущих потоков, в которых runnables принимает элементы один за другим из очереди.

или

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

или

подкласс BlockingQueue по вашему выбору и создать метод "Collection take (int i)" с переписанной версией обычного take().

Ещё вопросы

Сообщество Overcoder
Наверх
Меню