Разбираюсь с потоками, написал такой код:
public class main {
public static void main(String[] args) {
Horse horsik = new Horse();
Thread tr1 = new Thread(horsik, "Anna");
tr1.start();
horsik.horseStop();
}
public static class Horse implements Runnable{
public void horseStop(){
String trName = Thread.currentThread().getName();
System.out.println(trName);
Thread.currentThread().interrupt();
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()){
}
}
}
}
Пытаюсь из метода main, через статический метод написанный в классе - остановить поток, но не работает. Объясните пожалуйста почему?
Для завершения потока нужно завести флаг, в методе horseStop этот флаг устанавливать, и выходить и из run по этому флагу.
public class main {
public static void main(String[] args) {
Horse horsik = new Horse();
Thread tr1 = new Thread(horsik, "Anna");
tr1.start();
horsik.horseStop();
}
public static class Horse implements Runnable{
boolean stop = false;
public void horseStop(){
String trName = Thread.currentThread().getName();
System.out.println(trName);
stop = true;
}
@Override
public void run() {
while (!stop){
}
}
}
}
Начнем с того, что это называется не усыпить, а прервать.
Этот код не работает так как вы ожидаете потому, что метод horseStop вызывается в главном потоке (т.е. потоке который выполняет метод main). А остановить вы хотите другой поток, тот который выполняет метод Horse.run. Поэтому сигнал прерывания посылается не тому потоку, которому вы хотите его послать.
Thread.currentThread() возвращает текущий поток, из которого собственно происходит вызов этой функции. Вам же нужно вызывать interrupt на объекте tr1. Так как ссылка на объект tr1 недоступна внутри horseStop, то придется унаследовать Horse от Thread:
class Horse extends Thread {
public void horseStop(){
String trName = this.getName();
System.out.println(trName);
this.interrupt();
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()){
}
}
}
Только учтите, что правильно проверять на прерывание внутри run нужно так:
try {
// делаем что-то
} catch (InterruptedException e) {
// нас прервали
}
Я тоже не люблю наследоваться от Thread, поэтому юзаю такой метод:
public static void main(String[] args) {
Horse horsik = new Horse();
horsik.horseStop();
}
public static class Horse implements Runnable {
Thread t;
public Horse() {
this.t = new Thread("Anna");
this.t.start();
}
public void horseStop() {
String trName = this.t.getName();
System.out.println(trName);
this.t.interrupt();
}
@Override
public void run() {
while (!Thread.interrupted()) {
}
}
}
Продвижение своими сайтами как стратегия роста и независимости