Вот мой прецедент.
Устаревшая система обновляет таблицу очередей базы данных QUEUE.
Мне нужна запланированная повторяющаяся работа, которая - проверяет содержимое QUEUE - если в таблице есть строки, они блокируют строку и выполняют некоторую работу - удаляет строку в QUEUE
Если предыдущее задание все еще запущено, то для выполнения этой работы будет создан новый поток. Я хочу настроить максимальное количество одновременных потоков.
Я использую Spring 3, и мое текущее решение состоит в том, чтобы сделать следующее (используя fixedRate 1 миллисекунды, чтобы потоки выполнялись в основном непрерывно)
@Scheduled(fixedRate = 1)
@Async
public void doSchedule() throws InterruptedException {
log.debug("Start schedule");
publishWorker.start();
log.debug("End schedule");
}
<task:executor id="workerExecutor" pool-size="4" />
Это создало 4 потока прямо, и потоки правильно распределяли рабочую нагрузку из очереди. Однако я, кажется, получаю утечку памяти, когда потоки занимают много времени.
java.util.concurrent.ThreadPoolExecutor @ 0xe097b8f0 | 80 | 373,410,496 | 89.74%
|- java.util.concurrent.LinkedBlockingQueue @ 0xe097b940 | 48 | 373,410,136 | 89.74%
| |- java.util.concurrent.LinkedBlockingQueue$Node @ 0xe25c9d68
Итак,
1: Должен ли я использовать @Async и @Scheduled вместе?
2: Если нет, то как еще я могу использовать Spring для выполнения моих требований?
3: Как создать новые потоки только тогда, когда другие потоки заняты?
Спасибо всем!
EDIT: Я думаю, что очередь заданий становилась бесконечно длинной... Теперь, используя
<task:executor id="workerExecutor"
pool-size="1-4"
queue-capacity="10" rejection-policy="DISCARD" />
Отчитается с результатами