Подтвердить что ты не робот

Как остановить поток, созданный при реализации runnable-интерфейса?

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

4b9b3361

Ответ 1

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

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

Примечание. Хотя Thread.interrupted() кажется таким же, как isInterrupted(), он имеет неприятный побочный эффект: вызов interrupted() очищает флаг interrupted, а вызов isInterrupted() - нет.

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

Ответ 2

Как остановить поток, созданный при реализации интерфейса runnable?

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

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

Вы также можете установить флаг прерывания в потоке, который вы можете проверить, и который вызывает sleep(), wait() и некоторые другие методы для throw 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;
    }
}

Ответ 3

Если вы используете ThreadPoolExecutor и используете метод submit(), он предоставит вам Future назад. Вы можете вызвать cancel() в возвращаемом будущем, чтобы остановить свою задачу Runnable.

Ответ 4

Остановка потока на полпути не является хорошей практикой. Более подходящим способом является обратная передача потока. Пусть объект 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);
    }
}

Ответ 5

Остановка (убийство) нити в середине пути не рекомендуется. API фактически не рекомендуется.

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

Ответ 6

Thread.currentThread(). isInterrupted() отлично работает. но это код только приостанавливает таймер.

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

 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();


                        }


                    });


                }`