Java поток start () без join () или interrupt () в сервлете - PullRequest
2 голосов
/ 01 сентября 2009

У меня есть фильтр сервлетов, который несет некоторую логику и производит вывод до того, как запрос будет обслуживаться его основной страницей. У меня есть новая необходимость отправить вывод на несколько секунд позже, чем в тот момент, когда он генерируется (с задержкой ~ 10 с). Из-за некоторых неудачных дизайнерских решений, сделанных ранее, я не могу переместить положение фильтра, чтобы получить результат, отправленный после.

Я решил создать поток и задержать передачу сообщения туда. В настоящее время я не предпринимаю никаких явных шагов, чтобы остановить выполнение этого потока. Я не уверен, что все очищается должным образом. Должен ли я использовать join () или interrupt () или любые другие методы Thread для безопасной очистки после этого?

Так что в основном коде сервлета у меня есть что-то вроде этого ...

Thread t = new Thread(new MessageSender(message, 10000));
t.start();
//Carry on.. la la la

Хотя в этом классе есть и другие поля, я просто отбросил множество несущественных вещей, таких как подключение к БД и т. Д., Чтобы прояснить ситуацию.

private static class MessageSender implements Runnable {
    String message;
    int delay;

    public MessageSender(String message, int delay) {
        this.message = message;
        this.delay = delay;
    }

    public void run() {
        try {
            Thread.sleep(delay);
            System.out.println(new java.util.Date() + ": hello world");                
        } catch (InterruptedException e) {
            // Do blah
        } catch (Exception e) {
            // Do blah blah
        } finally {
            // Close connections and stuff
        }
    }
}

Ответы [ 4 ]

4 голосов
/ 01 сентября 2009

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

Однако я бы посоветовал не использовать необработанные потоки, а использовать java.util.concurrent.ScheduledExecutorService, создавая java.util.concurrent.Executors. Это более приятная абстракция, которая лучше контролирует распределение потоков.

1 голос
/ 02 сентября 2009

В спецификации сервлета прямо указано (раздел «Потоковая безопасность»), что объекты запросов и ответов не гарантируют поточно-ориентированность и что если эти объекты передаются другим потокам, то приложение отвечает за обеспечение того, объекты синхронизируются и доступ к ним возможен только в рамках метода обслуживания сервлета. Другими словами, вы должны .join () эти темы.

1 голос
/ 01 сентября 2009

Да, все будет правильно убрано. Поток умирает после завершения метода run (), и поскольку у вас больше нет ссылок на этот объект потока, он будет должным образом очищен от мусора.

Просто убедитесь, что на объект "Thread t" ничего не будет ссылаться. Чтобы быть уверенным в этом, вы можете использовать: (новая тема (...)). start ();

0 голосов
/ 31 мая 2012

Я просто должен был ответить на тот же вопрос сам:)

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

В Unix-системе вы можете использовать команду ps, но я ржавый, поэтому я спросил Google вместо чтения man-страницы. Одним из первых обращений в Google было Этот скрипт, в котором перечислены темы для каждого процесса . Вывод выглядит так

PID TID CLS RTPRIO  STAT    COMMAND WCHAN
....
16035   16047   TS  -   S   (java)  
16035   16050   TS  -   S   (java)  
16035   16054   TS  -   S   (java)  
16035   16057   TS  -   S   (java)  
16035   16058   TS  -   S   (java)  
16035   16059   TS  -   S   (java)  
16035   16060   TS  -   S   (java)  
....

И я просто grep вывод для идентификатора процесса (pid) процесса, который я хочу просмотреть и подсчитать количество строк, каждая из которых соответствует потоку. Как это:

morten@squeeze: ~$ sh /tmp/list_threads.sh | grep 16035 | wc -l
20

Итак, программа, которую я сейчас смотрю (PID 16035), имеет 20 запущенных потоков.

Это не требовало знания jconsole или каких-либо изменений в коде. Последняя часть, вероятно, самая важная, так как я сам не написал программу, поэтому теперь мне не нужно читать и понимать программу.

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