Подход кометы: возвращать поток в пул ExecutorService вместо сна в течение определенного интервала
Я пытаюсь реализовать кометный подход для Facebook, такой как push-уведомления браузера, следующим образом:
- HTTP-запрос выполняется к простому сервлету с использованием AJAX, он передается в java.util.concurrent.Executor (используя AsyncContext) и поток HTTP немедленно освобождается. Этот запрос выбирается фоновым потоком.
- Этот фоновый рабочий поток в пуле потоков продолжает проверять наличие новых уведомлений каждые 30 секунд (база данных запросов). Если есть какое-либо уведомление, ответ отправляется. В противном случае после определенного времени ожидания, т.е. 5 минут, отправляется ответ "No Notification". Клиент немедленно делает новый запрос, и процесс повторяется.
Проблема в том, что я использую Thread.sleep(30000) для периодической проверки данных. Для каждого запроса по-прежнему занят один поток. Это время (30 секунд) теряется, и поток остается недоступным для обработки любого другого запроса.
Есть ли какая-либо техника, которую я могу использовать, чтобы вернуть поток в пул сразу после того, как он проверил наличие новых уведомлений? И затем какой-нибудь другой доступный поток из пула делает то же самое через 30 секунд, чтобы проверить уведомления и так далее?
Код выглядит так:
// Creation of a global async Executor on ServletContextListener. contextInitialized
Executor executor =
new ThreadPoolExecutor(1, 1, 50000L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(100));
// Delegate the request to async thread
executor.execute(new RunnableClass(asyncContext));
// In RunnableClass.run() method
while(timeout5Min)
{
boolean newNotificationPresent = checkIfNotificationPresent(reqId);
if(!newNotificationPresent)
Thread.sleep(30000);
}
// send response
Может ли ScheduledThreadPoolExecutor как-то использоваться в таком случае? Любая другая техника?
1 ответ
Если вы ищете эффективность потока, вы должны смотреть на актеров. Посмотрите на Акку
В противном случае, не спите, запланируйте перепроверку, используя java.util.Timer