Прерывание нормально работающего потока в java

Я пытаюсь прервать нормально работающий поток (который не находится в состоянии сна() или ожидания()).

во время прохождения в сети я узнал, что прерывание нормально работающего потока просто установит флаг true и продолжит процесс.

Фрагмент кода

one.java

......
......
actionperformedmethod {

if (actionCmd.equals("cancel")) {
    try {
        r1.stop();  // to two.java
    } catch (InterruptedException ex) {
        ....
        ....
    }
}
}

in two.java

.....
.....
stop method() throws InterruptedException{
        if(!(t.isInterrupted())){
            t.interrupt();
            throw new InterruptedException();
        }
}

из two.java, когда я выбрасываю InterruptedException, я могу получить блок исключений в one.java, но как мне остановить поток после этого, потому что даже после этого поток, кажется, продолжает нормальный процесс.

Я новичок в концепциях потоков, пожалуйста, помогите ..


person madhu    schedule 23.04.2014    source источник
comment
Это может быть вам интересно stackoverflow.com/questions/10961714/ ?   -  person Developer Marius Žilėnas    schedule 23.04.2014


Ответы (3)


Прерывание не остановит поток. он просто устанавливает флаг в значение true, чтобы сигнализировать потоку о скорой остановке выполнения.

чтобы остановить выполнение, добавьте глобальную переменную как

private volatile boolean exit = false;

и вы добавляете один метод в свой 2-й класс

public void requestExit(){
  exit = true;
 }

внутри run () вашего потока сделайте что-то вроде этого

 if (exit == true){
    return;
   }

всякий раз, когда вы хотите позвонить, просто вызовите этот метод requestExit() из вашего main() или где бы вы ни хотели остановиться

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

дайте мне знать по любым вопросам

person Karibasappa G C    schedule 23.04.2014
comment
Спасибо за ответ .. Внутри метода запуска у меня есть около 6 методов. Я сомневаюсь, где я должен поставить галочку (exit == true) ?? должен ли он быть там перед каждым вызовом метода внутри run()? - person madhu; 23.04.2014
comment
да, лучше продолжать в начале, но опять же, если вы хотите, чтобы некоторые методы выполнялись обязательно, тогда поместите это условие после вызова этих методов. - person Karibasappa G C; 23.04.2014
comment
Да, в начале метода запуска у меня есть этот выход == true, проверьте мой квест, если программа выполняет третий метод внутри run (), и теперь я прерываю поток, я могу узнать это только после того, как третий метод завершит свое выполнение? ( потому что у меня будет проверка (exit == true) перед четвертым методом) - person madhu; 23.04.2014
comment
да, вот почему я сказал вам поставить в начале... и если вы хотите, чтобы он останавливался в каждой точке, тогда поместите это условие перед каждым вызовом метода и так, чтобы всякий раз, когда вы вызываете, он останавливался... но если ваш метод выполнение между ними может быть остановлено только в том случае, если вы поместите ту же логику остановки внутри своего метода... это зависит от ваших потребностей, где вы хотите остановиться - person Karibasappa G C; 23.04.2014

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

public void run() {
  openSomeResources();
  try {
    while(notFinished) {
      if(Thread.interrupted()) return;
      doSomeStuff();
    }
  } finally {
    closeTheResources();
  }
}

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

Однако обратите внимание, что любой метод блокировки, выдающий InterruptedException, сбрасывает флаг прерывания при выдаче этого исключения. Поэтому для того, чтобы такая проверка работала, вы должны повторно прерывать себя всякий раз, когда получаете InterruptedException

try {
  Thread.sleep(3000);
} catch(InterruptedException e) {
  // we were interrupted - set the flag so the next interrupted() check will
  // work correctly.
  Thread.currentThread().interrupt();
}
person Ian Roberts    schedule 23.04.2014
comment
вот как написать красивый ответ! - person p_champ; 18.12.2018

Потоки работают только тогда, когда их метод run() находится в стеке, поэтому обычно люди помещают while(true) в метод запуска, все, что вам нужно сделать в потоке, чтобы остановить его, это return где-нибудь в методе запуска или разорвать цикл, как только метод run() больше не работает, поток остановлен.

person Basim Khajwal    schedule 23.04.2014
comment
Если выполнение в методе запуска находится на полпути, как я могу использовать цикл возврата или прерывания на основе флага прерывания?? - person madhu; 23.04.2014