Можно ли хранить объект Thread в атрибуте сеанса или приложения? - PullRequest
1 голос
/ 06 декабря 2010

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

Когда пользовательЗаходите в систему, мне нужен поток, который будет периодически опрашивать сервер веб-сервисов и получать обновления.Когда пользователь выходит из системы, я хочу остановить / приостановить поток.

Если я создаю поток, когда пользователь входит в систему, мне нужна ссылка на этот поток, если я хочу приостановить его, когда пользователь вышел из системыи затем запустите его снова, когда они войдут в систему.

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

Тогда, когда в следующий раз пользователь войдет в систему, я смогу создать новый фоновый поток?

*** Мне нужно, чтобы поток работал в фоновом режиме и опрашивал сервер веб-служб на наличие обновлений, которые я использую для обновления своей базы данных.Он может опрашивать один раз каждые 5 минут.

Я не хочу, чтобы он все время опрашивался, поэтому я и пытался управлять им в зависимости от того, вошел ли пользователь в систему или нет ... Я настраиваллогическое значение работает в false, когда они выходят из системы, чтобы остановить поток.Поскольку поток был сохранен в контексте приложения, я мог бы затем установить значение true для запуска, когда они снова войдут в систему.

Что можно сказать о потоке, работающем в фоновом режиме и проверяющем что-то, например, что ваш Интернет работает?

Я знаю, как создать поток, но я запутался в том, как его прекратить, поскольку он должен постоянно работать в фоновом режиме.

Использую ли я потоки не по назначению?я должен использовать что-то еще?

Еще раз спасибо, надеюсь, это лучшее объяснение ...

Ответы [ 4 ]

3 голосов
/ 06 декабря 2010

Поток не сериализуем, поэтому его сохранение в сеансе может быть проблематичным.

Кроме того, остановка или приостановка потока может быть проблематичной, если вы не наберете код Runnable потока, чтобы периодически проверять, был ли он приостановлен / остановлен, и действовать соответственно. (Методы Thread.stop() и Thread.pause() устарели, и вам следует избегать их использования. Они могут потенциально дестабилизировать вашу JVM.)

Даже если вы решите вышеуказанные проблемы, существует множество проблем управления ресурсами, которые необходимо решить.

Я не уверен, что я на правильном пути

Короче говоря, вы не, ИМО.

Вы не объяснили , почему вам нужно ассоциировать поток с каждым сеансом или для чего предназначены эти потоки. Если вы это сделаете, вы получите несколько хороших предложений для альтернативных подходов, которые (в значительной степени) позволяют избежать проблем, описанных выше.

Followup

Я не использовал .stop и .pause.

Хорошо.

Я использовал логическое «runnable» для управления потоком.

Это одна альтернатива. Я предпочитаю использовать механизм Thread.interrupt(), поскольку он позволяет прерывать поток, заблокированный в операции ввода-вывода или при wait(...) вызове stop.

Что если вы опрашиваете устройство и вам нужен доступ к возвращенным данным? Каков наилучший подход?

Вероятно, наилучшим подходом является создание потока или пула потоков при инициализации сервлета, который отвечает за опрос устройств. Если вам нужно сохранить возвращенные данные, чтобы к ним можно было получить доступ в последующем HTTP-запросе, поместите их в (скажем) очередь, к которой может обращаться контроллер запросов. Возможно, вам понадобится некоторая инфраструктура для удаления невыбранных объектов данных из очереди после определенного периода времени и т. Д.

3 голосов
/ 06 декабря 2010

Поскольку сами сервлеты будут создаваться несколько раз одновременно, создание еще большего количества потоков не является разумной идеей.У вас возникнут проблемы, если вы решите кластеризовать свое приложение на нескольких компьютерах из-за проблем с сериализацией, поэтому вы вначале блокируете себя.

Кроме того, кажется, что вашу проблему можно решить с помощью пула AJAX.со стороны клиента.Зачем объединять сервер веб-сервисов и получать обновления, если вы не можете показать их своему клиенту без обновления всей страницы?

Подумайте об этом сценарии: если сеанс пользователя длится 30 минут, а пользователь не делаетВыйдите из системы, но просто закройте окно браузера: вы не будете знать, что это произошло, и в течение следующих 30 минут вы будете использовать этот веб-сервис, что является пустой тратой ресурсов.

1 голос
/ 06 декабря 2010

Вы действительно не должны создавать потоки внутри контейнеров вообще. Для чего это?

И если он предназначен для использования другими сервлетами, он скорее будет принадлежать атрибутам приложения, а не атрибутам сеанса, не так ли? или вы действительно создаете тему для каждого пользователя? что вы действительно не хотите делать.

0 голосов
/ 06 декабря 2010

Я вижу, что могут быть веские причины для выполнения опроса на стороне сервера в фоновом потоке: например, это может занять больше времени, чем пользователь хочет дождаться ответа на запрос.И есть проблема в том, что некоторые антидискриминационные законы (точнее, инструкции по толкованию этих законов) запрещают использование JavaScript, поэтому нет Ajax.

Так что, если на самом деле нет другого пути,Я предлагаю создать один поток (или очень маленький пул потоков) в Servlet.init ().Этот единственный (или небольшое количество потоков) должен сделать опрос для всех активных пользователей.В web.xml вы можете определить прослушиватель сеансов, чтобы вы могли отслеживать открытые и закрытые / просроченные сеансы.

Убедитесь, что в Servlet.destroy () указано, что поток (ы) должен существовать.

Чтобы определить прослушиватель активного цикла сеанса, добавьте его в web.xml:

<listener>
    <listener-class>
        com.example.SessionListener
    </listener-class>
</listener>

И затем запомните открытые сеансы, чтобы их можно было перебирать в фоновом потоке.

public class SessionListener implements HttpSessionListener {
    private Set<HttpSession> sessions = Collections.synchronizedCollections(
         new HashSet<HttpSession>());

    public void sessionCreated(HttpSessionEvent sessionEvent) {
        HttpSession session = sessionEvent.getSession();
        sessions.add(session;
    }

    public synchronized void sessionDestroyed(HttpSessionEvent sessionEvent) {
        HttpSession session = sessionEvent.getSession();
        sessions.remove(session);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...