Java, Tomcat, ServletContextListener и фоновый поток - PullRequest
2 голосов
/ 21 апреля 2011

У меня есть сервлет, который обрабатывает определенный входящий запрос.Мы назовем это UpdateUserStats.Я хочу, чтобы звонок был быстрым, но мне также нужен запрос для выполнения достаточно дорогой задачи.Я подумал, что это может быть хорошим решением, если я позволю сервлету UpdateUserStats выполнить всю работу, которая определяет успех или неудачу, сохранит новое состояние, а затем поставит в очередь некоторую работу для фонового потока, чтобы позаботиться и немедленно вернуть успех.1001 *

Это кажется хорошим, но мне интересно, как справиться с выключением.Когда сервер выключается, я хочу убедиться, что он не уничтожает фоновый поток, пока не останется больше работы.Я думал об использовании tomcat ServletContextListener, чтобы фоновый поток знал, что сервер отключается, и можно завершить работу, когда очередь заканчивается, но я не уверен на 100%, как это будет себя вести.Будет ли contextDestroyed() только после того, как все запросы будут обработаны?Интерфейс, кажется, подразумевает это, но я не нашел его в документации.Кроме того, мне интересно, сколько времени Tomcat готов подождать, прежде чем разозлиться, что фоновый поток не завершается.

Альтернативно, есть ли лучший способ справиться с этой проблемой?Это приложение Spring, если, возможно, Spring обладает какой-то волшебной функциональностью фоновой работы после запроса.

Ответы [ 3 ]

1 голос
/ 21 апреля 2011

Вы можете использовать ThreadPool с максимальным количеством потоков приложения, тогда он будет поставлен в очередь всякий раз, когда это необходимо, и может конфигурироваться на основе аппаратного и потокового задания.Для этого вам нужно использовать ExecutorService: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

ThreadPool может инициализироваться, как показано ниже

executorPool = Executors.newFixedThreadPool (50);

В вашем сервисном методе вы можете определить метод отправки в поток следующим образом: executorPool.submit (new ProcessTask ());

Очистку ThreadPool можно выполнить, как показано ниже, во время уничтожения / завершения работы (приложение)executorPool.shutdownNow ();

Надеюсь, что это полезно

1 голос
/ 21 апреля 2011

На основе спецификаций сервлета

"При завершении работы приложения слушатели уведомляются в обратном порядке к их объявлениям с уведомлениями для слушателей сеанса, предшествующими уведомлениям для слушателей контекста. Слушатели сеанса должны быть уведомлены о недействительности сеанса до прослушивателей контекста уведомление о закрытии приложения. "

Так что это должен быть первый слушатель, который обрабатывает уведомление потока о завершении своей работы.

Я использовал tomcat и, насколько я видел, он не будет ждать более 10-15 секунд, прежде чем прекратит чистое отключение, если к тому времени слушатель не завершит работу.

Обычно все контейнеры, такие как Spring, используют слушатель для чистого выхода во время выключения

1 голос
/ 21 апреля 2011

Упоминая об альтернативе, вы можете создать очередь в отдельной JVM (используйте ActiveMQ, RabbitMQ или что-то еще более простое).Таким образом, задание, помещенное в очередь, будет обработано, даже если tomcat выйдет из строя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...