Поток Java прерывает и присоединяется (поток еще жив после объединения) - PullRequest
2 голосов
/ 29 января 2010

Я пытаюсь выяснить какое-то поведение. У меня есть код, который порождает один поток. Он ждет некоторое время, а затем прерывает его, присоединяет его и затем выходит из метода.

.
.
.
try {
        Thread.sleep(processForMillis);
    }
    catch (InterruptedException ex) {
        // Won't happen, ignore.
    }

    for (Thread t : threads) {
        logger.debug("Interrupting Thread " + t.getName());
        t.interrupt();
    }

    for (Thread t : threads) {
        try {
            t.join(1000L);
            logger.debug("Joined Thread " + t.getName());
            logger.debug("isAlive? " + t.isAlive());
        }
        catch (InterruptedException ex) {
            // this will never happen
            logger.debug("InterruptionException while joining, but didn't expect it.");
        }
    }
} // end of method

Я сейчас запускаю это только с одним потоком. Я вижу в своих журналах, что обычно isAlive () будет ложным после объединения, но иногда оно все еще живо. Поток находится в цикле while:

while(!Thread.currentThread().isInterrupted()){
.
// do some blocking io stuff here
}

Итак, я подозреваю, что происходит то, что мы прерываем поток, пока он читает / обрабатывает входной поток (блокируя io), и это занимает больше времени, чем требуется для выполнения условного условия и завершения соединения.

Итак, мой вопрос, что происходит с потоком?

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

Ответы [ 2 ]

1 голос
/ 29 января 2010

interrupt () просто устанавливает флаг в потоке, что он был прерван. Многие блокирующие вызовы не разблокируются, когда это происходит, это означает, что прерывание не влияет на поток и продолжает делать свое дело (например, блокировка на InputStream).

Я предполагаю, что в некоторых случаях поток не разблокируется и не достигает условия while в течение заданного времени соединения (1 секунда здесь), в других случаях вызов блокировки завершается в течение времени ожидания, и поток заканчивается. 1003 *

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

0 голосов
/ 29 января 2010

В дополнение к ответу nos, для прерывания блокирующего вызова IO можно close() его поток

...