У меня есть список рабочих подразделений, и я хочу обрабатывать их параллельно. Работа блока составляет 8-15 секунд каждый, полностью расчетное время, без блокировки ввода-вывода. Чего я хочу добиться, так это иметь ExecutorService, который:
не создает ни одного потока, когда нет работы
при необходимости можно динамически масштабировать до 20 потоков
разрешить добавлять все рабочие единицы одновременно (без блокировки отправки)
Queue queue = new ConcurrentLinkedDeque();
ExecutorService service = ....
for(WorkUnit unit : list) {
service.submit(() -> {
.. do some work ..
queue.offer(result);
);
}
while(queue.peek() != null) {
... process results while they arrive ...
}
Я безуспешно пробовал:
Использование newCachedThreadPool() создает слишком много потоков
Затем я использовал его внутренний вызов new ThreadPoolExecutor(0, 20, 60L, SECONDS, new SynchronousQueue()), но потом я заметил, что submit() блокируется из-за синхронной очереди
Поэтому я использовал new LinkedBlockingQueue(), просто чтобы узнать, что ThreadPoolExecutor порождает только один поток
Я уверен, что существует официальная реализация для этого самого простого варианта использования параллелизма.
Может кто-нибудь посоветовать?
У меня есть список рабочих подразделений, и я хочу обрабатывать их параллельно. Работа блока составляет 8-15 секунд каждый, полностью расчетное время, без блокировки ввода-вывода. Чего я хочу добиться, так это иметь ExecutorService, который: [list] [*]не создает ни одного потока, когда нет работы[*]при необходимости можно динамически масштабировать до 20 потоков [*]разрешить добавлять все рабочие единицы одновременно (без блокировки отправки) [/list] Что-то вроде: [code]Queue queue = new ConcurrentLinkedDeque(); ExecutorService service = .... for(WorkUnit unit : list) { service.submit(() -> { .. do some work .. queue.offer(result); ); } while(queue.peek() != null) { ... process results while they arrive ... } [/code] Я безуспешно пробовал: [list] [*]Использование newCachedThreadPool() создает слишком много потоков [*]Затем я использовал его внутренний вызов new ThreadPoolExecutor(0, 20, 60L, SECONDS, new SynchronousQueue()), но потом я заметил, что submit() блокируется из-за синхронной очереди [*]Поэтому я использовал new LinkedBlockingQueue(), просто чтобы узнать, что ThreadPoolExecutor порождает только один поток [/list] Я уверен, что существует официальная реализация для этого самого простого варианта использования параллелизма. Может кто-нибудь посоветовать?