Как я могу убить нить? без использования stop();

Thread currentThread=Thread.currentThread();
        public void run()
        {               

             while(!shutdown)
            {                               
                try
                {
                    System.out.println(currentThread.isAlive());
                Thread.interrupted();

                System.out.println(currentThread.isAlive());
                if(currentThread.isAlive()==false)
                {
                    shutdown=true;
                }
                }
                catch(Exception e)
                {
                    currentThread.interrupt();
                }                   
            }
        }

    });
    thread.start();

3 ответа

Альтернативой вызову stop является использование прерывания, чтобы сообщить потоку, что вы хотите, чтобы он завершил свою работу. (Это предполагает, что поток, который вы хотите остановить, ведет себя хорошо, если он игнорирует InterruptedException, съедая их сразу после их выброса, и не проверяет статус прерывания, тогда вы возвращаетесь к использованию stop().)

Вот некоторый код, который я написал как ответ на вопрос о потоке, это пример того, как работает прерывание потока:

public class HelloWorld {

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Runnable() {

            public void run() {
                try {
                    while (!Thread.currentThread().isInterrupted()) {
                        Thread.sleep(5000);
                        System.out.println("Hello World!");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        thread.start();
        System.out.println("press enter to quit");
        System.in.read();
        thread.interrupt();
    }
}

Некоторые вещи, которые нужно знать:

  • Прерывающие причины sleep() а также wait() немедленно бросить, иначе вы застряли в ожидании времени сна, чтобы пройти.

  • Обратите внимание, что нет необходимости в отдельном логическом флаге.

  • Остановленный поток взаимодействует, проверяя статус прерывания и перехватывая InterruptedExceptions вне цикла while (используя его для выхода из цикла). Прерывание - это единственное место, где можно использовать исключение для управления потоком, и в этом весь смысл.

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

Некоторые замечания о размещенном коде:

  • Размещенный пример неполон, но помещать ссылку на текущий поток в переменную экземпляра кажется плохой идеей. Он будет инициализирован для любого потока, создающего объект, а не для потока, выполняющего метод run. Если один и тот же экземпляр Runnable выполняется более чем в одном потоке, переменная экземпляра не будет отражать нужный поток большую часть времени.

  • Проверка того, является ли поток работоспособным, всегда всегда приводит к значению true (если только не возникает ошибка, когда переменная экземпляра currentThread ссылается на неправильный поток), Thread#isAlive Ложь только после того, как поток завершил выполнение, он не возвращает ложь только потому, что он был прерван.

  • призвание Thread#interrupted приведет к очистке флага прерывания, и здесь не имеет смысла, тем более что возвращаемое значение отбрасывается. Точка вызова Thread#interrupted чтобы проверить состояние прерванного флага, а затем очистить его, это удобный метод, который используется InterruptedException,

Как правило, поток прерывается, когда он прерывается. Итак, почему бы не использовать родной логический? Попробуйте isInterrupted ():

   Thread t = new Thread(new Runnable(){
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                // do stuff         
            }   
        }});
    t.start();

    // Sleep a second, and then interrupt
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}
    t.interrupt();

Хороший способ сделать это - использовать логический флаг для обозначения потока.

class MyRunnable implements Runnable {

    public volatile boolean stopThread = false;

    public void run() {
            while(!stopThread) {
                    // Thread code here
            }
    }

}

Создайте экземпляр MyRunnable с именем myrunnable, оберните его в новый Thread экземпляр и запустить экземпляр. Если вы хотите пометить поток как остановившийся, установите myrunnable.stopThread = true. Таким образом, это не останавливается посреди чего-то, только там, где мы ожидаем, что это остановится.

Другие вопросы по тегам