Автор - java-программист из Гуанчжоу. Я только что закончил полгода назад. В свободное время пишу блог. Если вы считаете, что мои статьи хорошо написаны, вы можете подписаться на мой публичный аккаунт WeChat (J2 Binbin), там будет более захватывающий контент. Я начал вести блог в августе 2018 года и надеюсь написать больше простых для понимания технических статей, чтобы поделиться ими с вами в будущем.
предисловие
Вы когда-нибудь задумывались, как остановить нить? Многие люди сначала думают о методе Thread.stop(), но этот метод устарел и не рекомендуется, потому что этот метод вызовет проблемы с безопасностью, какие проблемы с безопасностью? Подробности будут сообщены позже. Давайте поговорим о методе Thread.interrupt(), который в настоящее время рекомендуется JDK API для остановки потоков.
Thread.interrupt()
Поскольку поток не может быть остановлен напрямую, есть только один способ завершить поток — разрешить завершение метода run. Thread.interrupt() означает «остановить, прервать». Но этот метод должен добавить суждение, чтобы завершить остановку потока. Как только будет обнаружено, что поток находится в прерванном состоянии, есть возможность завершить метод выполнения. Давайте рассмотрим пример кода, чтобы увидеть, как он останавливает поток?
1. interrupt() останавливает поток
package com.bingo.thread.stopThread;
/**
* Created with IntelliJ IDEA.
* Description: 停止线程不推荐使用stop方法,此方法不安全,我们可以使用Thread.interrupt()
* User: bingo
*/
public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
myThread.interrupt();
System.out.println("end...");
}
}
class MyThread extends Thread{
@Override
public void run() {
super.run();
for (int i = 0; i < 10000 ; i++) {
if(this.isInterrupted()){
System.out.println("已经是停止状态了,我要退出了");
break;
}
System.out.println("i="+(i+1));
}
}
}
результат операции:
i=1
......
i=3102
i=3103
i=3104
i=3105
i=3106
i=3107
i=3108
end...
已经是停止状态了,我要退出了
Результаты выполнения Мы видим, что когда цикл потока myThread достигает i=3108, он выходит из цикла, потому что поток прерывается.Этот пример является хорошим объяснением эффекта метода прерывания.
2. Прерывание может очистить замороженное состояние потока и восстановить поток в работоспособное состояние.
package com.bingo.thread.stopThread;
/**
* Created with IntelliJ IDEA.
* Description: interrupt可以清除线程的冻结状态,让线程恢复到可运行的状态上来。
* User: bingo
*/
public class Run2 {
public static void main(String[] args) {
MyThread2 thread = new MyThread2();
thread.start();
thread.interrupt();
System.out.println("main end...");
}
}
class MyThread2 extends Thread{
@Override
public void run() {
System.out.println("run begin...");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
System.out.println("run 在沉睡中被中止,进入catch");
e.printStackTrace();
}
System.out.println("run end...");
}
}
результат операции:
main end...
run begin...
run 在沉睡中被中止,进入catch
run end...
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.bingo.thread.stopThread.MyThread2.run(Run2.java:26)
Из результатов работы мы видим, что исходное время ожидания метода запуска составляет 1000 секунд, но результат печати мгновенный.Фактически, сон был прерван методом прерывания.В это время замороженное состояние поток очищается, и генерируется исключение, которое перехватывается Захват и печать информации об исключении.
Насилие Стоп - Стоп
На следующем рисунке приведено описание метода остановки в JDK API.Вы видите, что он устарел и устарел, и расскажите нам, почему этот метод небезопасен?
Если поток заблокирован, метод остановки снимает блокировку при остановке потока, что может привести к несогласованности данных. Следующий код может проиллюстрировать эту проблему.package com.bingo.thread.stopThread;
/**
* Created with IntelliJ IDEA.
* Description: stop()方法为何不安全?下面例子可解答
* User: bingo
*/
public class StopTest {
public static void main(String[] args) {
try {
SynchrionzedObject object = new SynchrionzedObject();
MyThread3 t = new MyThread3(object);
t.start();
Thread.sleep(500);
t.stop();
System.out.println(object.getUsername()+" "+object.getPassword());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class SynchrionzedObject{
private String username = "a";
private String password = "aa";
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public synchronized void printString(String username,String password){
try {
this.username = username;
Thread.sleep(10000);
this.password = password;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyThread3 extends Thread{
private SynchrionzedObject object;
public MyThread3(SynchrionzedObject object){
this.object = object;
}
@Override
public void run() {
object.printString("b", "bb");
}
}
результат операции:
b aa
Из приведенного выше примера видно, что хотя метод printString заблокирован, метод run внезапно останавливается и блокировка снимается. Поток MyThread только назначает имя пользователя, но действие по назначению пароля не выполняется. В это время данные противоречивы..
Наконец
На самом деле, многие методы многопоточности в Java являются нативными методами, которые основаны на внутренней реализации JVM, поэтому нам необходимо изучить эту часть контента в сочетании с JVM. Прогресс технологии требует каждого небольшого накопления, чтобы идти дальше и дольше.