В общем: есть websocket сервер, в него приходят запросы, которые я обрабатываю и складываю ответы в очередь (LinkedBlockingQueue).
Обработкой ответов занимается класс ResponseExecutor. Так как он работает с блокирующей очердью, данным способом получается снизить нагрузку на ЦП в моменты когда очередь пуста, т.к. метод .take() блокирует поток, но когда в очереди накапливается много ответов - то их обработка может длится долгое время, потому что не все потоки задействованы. Вот код класса ResponseExecutor:
public class ResponseExecutor {
private static final String TAG = ResponseExecutor.class.getSimpleName();
private Log log = new Log(TAG, false);
private final static int THREAD_POOL_SIZE = 16;
private ExecutorService executorService;
private LinkedBlockingQueue<ResponseValue> queue;
private ConcurrentHashMap<ServiceUser, CopyOnWriteArrayList<WSDeviceSessionWrapper>> users;
public ResponseExecutor(ConcurrentHashMap<ServiceUser, CopyOnWriteArrayList<WSDeviceSessionWrapper>> users, LinkedBlockingQueue<ResponseValue> queue) {
this.executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ExecutorThreadFactory());
this.users = users;
this.queue = queue;
}
public void processResponse(ResponseValue response) {
this.queue.add(response);
this.executorService.execute(new Consumer(this.users, this.queue));
}
private class Consumer implements Runnable {
private ConcurrentHashMap<ServiceUser, CopyOnWriteArrayList<WSDeviceSessionWrapper>> users;
private LinkedBlockingQueue<ResponseValue> queue;
public Consumer(ConcurrentHashMap<ServiceUser, CopyOnWriteArrayList<WSDeviceSessionWrapper>> users, LinkedBlockingQueue<ResponseValue> queue) {
this.users = users;
this.queue = queue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
ResponseValue value = queue.take();
process(value);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
break;
}
}
}
}
}
Я хочу вместо LinkedBlockingQueue использовать ConcurrentLinkedQueue но она съедает ЦП в моменты когда очередь пуста.
Вопрос: можно ли каким то образом использовать ConcurrentLinkedQueue и сделать так, что бы цикл while работал только когда в очереди есть данные?
P.S. была мысль прерывать все потоки после того как очередь стала пустой, но пока не до конца понял как это реализовать.
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники