Вопрос по multithreading, java – Как остановить поток, созданный с помощью запускаемого интерфейса?

49

Я создал класс, реализовав работающий интерфейс, а затем создал множество потоков (около 10) в каком-то другом классе моего проекта.
Как остановить некоторые из этих тем?

Ваш Ответ

6   ответов
67

Простейшие путь кinterrupt() это, что приведет кThread.currentThread().isInterrupted() возвращатьсяtrue, а также может броситьInterruptedException при определенных обстоятельствах, когда тема является Ожидания, напримерThread.sleep(), otherThread.join(), object.wait() так далее

Внутриrun() метод, который вам понадобится, чтобы поймать это исключение и / или регулярно проверятьThread.currentThread().isInterrupted() цени и сделай что-нибудь (например, вырвись).

Примечание: хотяThread.interrupted() похоже наisInterrupted(), у него неприятный побочный эффект: Звонокinterrupted() Рассеется theinterrupted флаг, тогда как вызовisInterrupted() не

Другие методы без прерывания включают использование «стоп» volatile) флаг, который отслеживает работающий поток.

У меня нетwhile в моей ветке, но иногда мне нужно остановить его, прежде чем он обработает все строки внутриrun метод user25
31

Существует множество способов остановить поток, но все они используют для этого определенный код. Типичный способ остановить поток - иметьvolatile boolean shutdown поле, которое поток проверяет так часто:

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }

Вы также можете прервать поток, который вызываетsleep(), wait() и некоторые другие методы броскаInterruptedException. Вы также должны проверить флаг прерывания потока с чем-то вроде:

  public void run() {
      while (!Thread.currentThread().isInterrupted()) {
          // continue processing
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              // good practice
              Thread.currentThread().interrupt();
              return;
          }
      }
  }

Обратите внимание, что это прерывание потока сinterrupt() волян обязательно заставит его немедленно сгенерировать исключение. Только если вы используете прерываемый метоInterruptedException быть брошенным.

Если вы хотите добавитьshutdown() метод вашего класса, который реализуетRunnable, вы должны определить свой собственный класс как:

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
В моем классе я написал метод, который устанавливает флаг (shutdown в вашем примере) в true. Но я не могу получить доступ к этому методу из другого класса, где мне нужно остановить поток. svkvvenky
Да, тебе нужно как-нибудь разоблачить это. Я обычно делаю что-то вродеpublic class MyClass implements Runnable { volatile boolean shutdown; public void run() { if (! shutdown) { ... } } }. Вы можете добавитьshutdown() метод, который устанавливает флаг выключения. Тогда вы бы сделалиnew Thread(new MyClass()).start(); чтобы запустить. Gray
У меня нетwhile в моей ветке, но иногда мне нужно остановить его, прежде чем он обработает все строки внутриrun метод user25
Затем вы можете использоватьif @ user25. Я бы потратил время, чтобы задать полный вопрос, если вам нужна дополнительная помощь. Gray
8

Останов Нить на полпути не очень хорошая практика. Более подходящий способ - заставить поток возвращаться программно. Пусть объект Runnable использует переменную общего доступа вrun() метод. Всякий раз, когда вы хотите остановить поток, используйте эту переменную в качестве флага.

EDIT: пример кода

class MyThread implements Runnable{

    private Boolean stop = false;

    public void run(){

        while(!stop){

            //some business logic
        }
    }
    public Boolean getStop() {
        return stop;
    }

    public void setStop(Boolean stop) {
        this.stop = stop;
    }       
}

public class TestStop {

    public static void main(String[] args){

        MyThread myThread = new MyThread();
        Thread th = new Thread(myThread);
        th.start();

        //Some logic goes there to decide whether to 
        //stop the thread or not. 

        //This will compell the thread to stop
        myThread.setStop(true);
    }
}
В моем классе я написал метод, который устанавливает флаг в false. Но я не могу получить доступ к этому методу из другого класса, где мне нужно остановить поток. svkvvenky
Это другой класс тот, который начинает поток? Santosh
да ты прав... svkvvenky
Если предположить, что класс, создавший поток, отвечает за его остановку, в этом классе должна сохраняться ссылка на экземпляр Runnable, и с помощью этой ссылки должен вызываться метод для установки флага. Santosh
Ты должен сделать свойstop переменная изменчивая. Jakub Kotowski
5

ThreadPoolExecutor, и вы используетеРазместить( метод, он даст вамFuture назад Ты можешь позвонитьОтмена( в возвращенном будущем, чтобы остановить тебяRunnable задача.

cancel пытается отменить выполнение, но не гарантирует его. Rohit
1

ки устарел.

Тем не менее, вы можете получить более подробную информацию, включая обходные пути здесь: Как вы убиваете нить в Java?

0

Thread.currentThread (). IsInterrupted () великолепно работает. но этот код только пауза таймера.

Этот код останавливает и сбрасывает таймер потока. h1 - имя обработчика. Этот код добавляется внутри слушателя нажатия кнопки. w_h = минуты w_m = миллисекунды i = счетчик

 i=0;
            w_h = 0;
            w_m = 0;


            textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
                        hl.removeCallbacksAndMessages(null);
                        Thread.currentThread().isInterrupted();


                        }


                    });


                }`

Похожие вопросы