почему interrupt () не работает должным образом и как он работает - PullRequest
5 голосов
/ 08 ноября 2011

Я хочу прервать поток, но вызов interrupt () кажется не работает, ниже приведен пример кода:

public class BasicThreadrRunner {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Basic(), "thread1");
        t1.start();
        Thread t3 = new Thread(new Basic(), "thread3");
        Thread t4 = new Thread(new Basic(), "thread4");
        t3.start();
        t1.interrupt();
        t4.start();
    }
}
class Basic implements Runnable{
    public void run(){
        while(true) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.err.println("thread: " + Thread.currentThread().getName());
                //e.printStackTrace();
            }
        }
    }
}

, но вывод выглядит так, что thead1 все еще работает.Кто-нибудь может объяснить, как работает interrupt (), спасибо

Ответы [ 2 ]

14 голосов
/ 08 ноября 2011

Поток все еще работает просто потому, что вы перехватываете InterruptedException и продолжаете работать.interrupt() в основном устанавливает флаг в объекте Thread, который можно проверить с помощью isInterrupted().Это также приводит к тому, что некоторые методы - sleep(), join Object.wait(), в частности - немедленно возвращаются, бросая InterruptedException.Это также приводит к немедленному завершению некоторых операций ввода-вывода.Если вы видите распечатки из вашего блока catch, то вы можете видеть, что interrupt() работает.

11 голосов
/ 08 ноября 2011

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

while(!Thread.currentThread().isInterrupted()){
    try{
        // do stuff
    }catch(InterruptedException e){
        Thread.currentThread().interrupt(); // propagate interrupt
    }
}

Использование циклической логики, такой как while(true), - просто ленивое кодирование. Вместо этого опрашивайте флаг прерывания потока, чтобы определить завершение через прерывание.

...