Пример: мне нужно обрабатывать миллионы записей, я хочу обрабатывать их параллельно, чтобы ускорить обработку. Для этой цели я хочу использовать пул потоков в Executor Service. Каждое задание занимает максимум несколько секунд. Чтобы не создавать миллион потоков для каждой записи в одном пуле потоков, что в моем случае приводило к проблемам с памятью, я решил обрабатывать записи партиями.
Я хочу использовать для каждого пакета новый пул потоков. Я заставляю Executor Service подождать, пока пакетные задачи не будут завершены, а затем выключу Executor Service и создаю новую для обработки следующей партии. Я делаю что-то вроде этого:
/*...................*/
int count = 1;
ExecutorService executor = buildExecutor(CORE_THREADS, MAX_THREADS);
while (/* there is a record */) {
executor.execute(new ProcessRecordThread(record));
count++;
if (count % BATCH_SIZE == 0) {
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
executor = buildExecutor(CORE_THREADS, MAX_THREADS);
}
}
/*................*/
Метод создания службы Executor
private static ExecutorService buildExecutor(int corePoolSize, int maximumPoolSize) {
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
Executors.defaultThreadFactory());
}
Я знаю, что создание пула потоков добавляет некоторые накладные расходы на обработку. Создание службы исполнителя в l oop считается плохой практикой. Есть ли какие-нибудь компромиссы, о которых я должен знать?
Есть ли способ, как добиться такого поведения, просто используя один пул потоков?