Вы должны каким-то образом задушить входящие запросы, и механизм их выполнения должен зависеть от работы, которую вы пытаетесь выполнить. Все остальное просто приведет к OOM при достаточной нагрузке и, таким образом, откроет вас для DOS-атак (даже непреднамеренных).
По сути, у вас есть 4 варианта:
- Заставьте клиентов ждать, пока вы не будете готовы принять их запросы
- Активно отклоняйте запросы клиентов, пока вы не будете готовы принимать новые запросы
- Разрешить клиентам тайм-аут при попытке связаться с вашим сервером, когда он не готов принимать запросы
- Смесь 2 или 3 из вышеуказанных стратегий.
Правильная стратегия зависит от того, как ваши реальные клиенты будут реагировать при различных обстоятельствах - лучше ли им ждать, возможно (эффективно) бесконечно, или лучше, чтобы они быстро знали, что их работа не будет выполнена, если только они попробуют позже?
Каким бы способом вы это ни делали, вам необходимо иметь возможность подсчитать количество задач, поставленных в очередь на текущий момент, и либо добавить задержку, полностью заблокировать, либо вернуть условие ошибки на основе количества элементов в очереди.
Простая стратегия блокировки может быть реализована с помощью реализации BlockingQueue. Однако это не дает особенно мелкозернистого контроля.
Или вы можете использовать семафор для управления разрешениями на добавление задач в очередь, что имеет преимущество в предоставлении метода tryAcquire (long timeout, TimeUnit unit), если вы хотите применить умеренное регулирование.
В любом случае, не позволяйте потокам, обслуживающим клиентов, расти без границ, иначе вы просто получите OOM по другой причине!