остановить нить
Остановка потоков — очень важный технический момент в многопоточной разработке Java.Многие предприятия имеют схожие требования в реальной работе.Освоение этой технологии может эффективно справляться с потоками, которые необходимо останавливать в бизнесе. Но остановить поток в языке Java не так просто, как с помощью оператора break, и нам нужно проделать сложную обработку.
Нам следует рассмотреть вопрос о том, как лучше остановить поток.Остановка потока означает остановку выполняемой им операции до того, как поток завершит обработку задачи, то есть отказ от текущей операции. Остановка потока раньше использовалась в старых JDK.Thread.stop()
метод, но позже обнаружил, что этот метод обработки очень опасен и небезопасен.Поскольку метод stop() был помечен как «устаревший/истекший» метод в JDK, он, очевидно, функционально несовершенен. Ответственному java-инженеру лучше не использовать,Потому что использование метода stop() для снятия блокировки приведет к противоречивым результатам для данных. Если это произойдет, данные, обрабатываемые программой, могут быть повреждены, что в конечном итоге приведет к неправильному ходу выполнения программы.Большинство операций, которые останавливают поток, используютThread.interrupt()
Несмотря на то, что имя метода означает «завершить, остановить», этот метод не завершает непосредственно запущенный поток и требует добавления суждения для завершения остановки потока.
Кроме того, в java есть следующие 3 метода для завершения работающего потока:
- Используйте флаг выхода, чтобы поток завершился нормально, то есть остановился, когда метод запуска завершится;
- Это использование метода остановки для принудительного завершения потока, как мы упоминали выше, что является просроченным и недопустимым методом.Этот метод можно исключить;
- Используйте метод прерывания для завершения потока.
Первый метод использования флажка выхода не будет представлен арендодателем. Подробности можно найти в других блогах. Все они похожи. Хозяин написал этот блог в основном для того, чтобы изучить преимущества и недостатки нескольких методов использования прерывания для остановки. потоки.
Метод исключения для остановки потока
Сначала мы останавливаем поток с помощью for-break:
public class ExceptionInterrupt extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
System.out.println("已经是停止状态了!我要退出了!");
break;
}
System.out.println("i=" + (i + 1));
}
System.out.println("我被输出,如果此代码是for又继续运行,线程并未停止!");
}
public static void main(String[] args) {
ExceptionInterrupt thread = new ExceptionInterrupt();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end!");
}
}
Результат печати следующий:
......
i=421200
i=421201
i=421202
i=421203
i=421204
i=421205
i=421206
i=421207
i=421208
i=421209
已经是停止状态了!我要退出了!
我被输出,如果此代码是for又继续运行,线程并未停止!
end!
Мы обнаружили, что хотя приведенный выше пример останавливает поток, если после оператора for есть оператор, он будет продолжать выполняться. Поэтому мы используем здесь метод исключения, чтобы остановить поток, и мы не будем продолжать выполнять бизнес-логику, стоящую за for.
public class ExceptionInterrupt2 extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500000; i++) {
if (this.isInterrupted()) {
System.out.println("已经是停止状态了!我要退出了!");
throw new InterruptedException();
}
System.out.println("i=" + (i + 1));
}
System.out.println("我在for下面");
} catch (InterruptedException e) {
System.out.println("进入ExceptionInterrupt2 类中run方法的catch了!");
e.printStackTrace();
}
}
public static void main(String[] args) {
ExceptionInterrupt2 thread = new ExceptionInterrupt2();
thread.start();
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
Результат печати следующий:
......
i=96487
i=96488
i=96489
i=96490
i=96491
i=96492
i=96493
已经是停止状态了!我要退出了!
进入ExceptionInterrupt2 类中run方法的catch了!
java.lang.InterruptedException
at com.thread.chapter1.ExceptionInterrupt2.run(ExceptionInterrupt2.java:20)
end!
Остановить поток в спящем режиме ()
Если поток остановит поток в состоянии сна(), каков будет эффект? Давайте посмотрим на следующий пример:
public class SleepInterrupt extends Thread{
@Override
public void run() {
super.run();
try {
System.out.println("run begin");
Thread.sleep(200000);
System.out.println("run end");
} catch (InterruptedException e) {
System.out.println("在沉睡中被停止!进入catch!"+this.isInterrupted());
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
SleepInterrupt thread=new SleepInterrupt();
thread.start();
Thread.sleep(200);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end");
}
}
Результат выполнения следующий:
run begin
end
在沉睡中被停止!进入catch!false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.thread.chapter1.SleepInterrupt.run(SleepInterrupt.java:18)
Из результата выполнения, если поток остановлен в состоянии сна, будет введен оператор catch, а значение состояния остановки будет очищено до значения false. В приведенном выше примере сначала нужно заснуть, а затем использовать прерывание () для остановки, и следует также отметить противоположную операцию.
public class SleepInterrupt2 extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 100000; i++) {
System.out.println("i=" + (i + 1));
}
System.out.println("run begin");
Thread.sleep(200000);
System.out.println("run end");
} catch (InterruptedException e) {
System.out.println("先停止,再遇到了sleep!进入catch!");
e.printStackTrace();
}
}
public static void main(String[] args) {
SleepInterrupt2 thread = new SleepInterrupt2();
thread.start();
thread.interrupt();
System.out.println("end");
}
}
Результат выполнения следующий:
......
i=99991
i=99992
i=99993
i=99994
i=99995
i=99996
i=99997
i=99998
i=99999
i=100000
run begin
先停止,再遇到了sleep!进入catch!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.thread.chapter1.SleepInterrupt2.run(SleepInterrupt2.java:21)
Используйте return, чтобы остановить поток
Комбинация метода interrupted() с return также может привести к остановке потока.
public class ReturnInterrupt extends Thread {
@Override
public void run() {
while (true) {
if (this.isInterrupted()) {
System.out.println("停止了!");
return;
}
System.out.println("time=" + System.currentTimeMillis());
}
}
public static void main(String[] args) throws InterruptedException {
ReturnInterrupt thread=new ReturnInterrupt();
thread.start();
Thread.sleep(2000);
thread.interrupt();
}
}
Результат выполнения следующий:
......
time=1536809054172
time=1536809054172
time=1536809054172
time=1536809054172
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
time=1536809054173
停止了!
резюме
Все вышеперечисленные методы используют прерывание для остановки потока, но используются разные методы.Однако для остановки потока рекомендуется использовать метод «генерация исключения», поскольку исключение также может быть выброшено вверх в блоке catch, чтобы остановить выполнение. события распространяются.
Ссылаться на
"Основная технология многопоточного программирования Java"