停止執行緒方法(interrupt)
阿新 • • 發佈:2018-12-09
java中有三種停止執行緒方法
1)使用退出標誌,使執行緒正常退出,也就是當run方法完成後執行緒終止。
2)使用stop方法方法強行終止執行緒,但是不推薦使用這個方法,應為stop不安全而且已經被廢棄的方法,還有suspend和resume都是廢棄的方法。
3)使用interrupt方法中斷執行緒。
講解第三種interrupt()方法 僅僅使房錢執行緒中打了一個停止的標記,並不是真的停止執行緒。程式碼如下:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { System.out.println("i=" + (i + 1)); } } }
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
}
}
執行緒沒有停止,而是列印完i
再分析下執行緒是否是停止的狀態
this.interrupted() 測試當前執行緒是否已經中斷。
this.isInterrupted()測試執行緒是否已經中斷。
兩者區別:(小白還是不懂,如果大神們知道還請您給我留個言解答下☺)
如下程式碼展示:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 50000; i++) { System.out.println("i=" + (i + 1)); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); //Thread.currentThread().interrupt(); System.out.println(thread.getName()+ " 是否停止1?="+thread.interrupted()); System.out.println(thread.getName()+ " 是否停止2?="+thread.interrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } public class Run2 { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); Thread.currentThread().interrupt(); System.out.println("是否停止1?=" + Thread.interrupted()); System.out.println("是否停止2?=" + Thread.interrupted()); System.out.println("end!"); } } public class Run3 { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("是否停止1?="+thread.isInterrupted()); System.out.println("是否停止2?="+thread.isInterrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
結果圖:
1:停止執行緒(異常法)
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.interrupted()) {
System.out.println("已經是停止狀態了!我要退出了!");
break;
}
System.out.println("i=" + (i + 1));
}
}
}
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
thread.sleep(2000);//執行緒睡2s 停止
// Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
上面的程式碼會出現下面問題:並沒有真正的退出執行緒
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 500000; i++) {
if (this.interrupted()) {
System.out.println("已經是停止狀態了!我要退出了!");
break;
}
System.out.println("i=" + (i + 1));
}
System.out.println("我被輸出,如果此程式碼是for又繼續執行,執行緒並未停止!");
}
}
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
解決如下
public class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500000; i++) {
if (this.interrupted()) {
System.out.println("已經是停止狀態了!我要退出了!");
throw new InterruptedException();//中斷異常
}
System.out.println("i=" + (i + 1));
}
System.out.println("我在for下面");
} catch (InterruptedException e) {
System.out.println("進MyThread.java類run方法中的catch了!");
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
2:在沉睡中停止執行緒
public class MyThread 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 class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(200);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
下面是先停止執行緒 再遇到sleep進入catch
public class MyThread 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(20000);
System.out.println("run end");
} catch (InterruptedException e) {
System.out.println("先停止,再遇到了sleep!進入catch!");
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
thread.interrupt();
System.out.println("end!");
}
}
3:使用stop()暴力停止執行緒。。會釋放當前物件持有的鎖
public class SynchronizedObject {
private String username = "a";
private String password = "aa";
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//注意這裡加同步方法 但是由於使用了stop方法 是物件釋放鎖
synchronized public void printString(String username, String password) {
try {
this.username = username;
Thread.sleep(100000);
this.password = password;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread extends Thread {
private SynchronizedObject object;
public MyThread(SynchronizedObject object) {
super();
this.object = object;
}
@Override
public void run() {
object.printString("b", "bb");
}
}
public class Run {
public static void main(String[] args) {
try {
SynchronizedObject object = new SynchronizedObject();
MyThread thread = new MyThread(object);
thread.start();
Thread.sleep(500);
thread.stop();
System.out.println(object.getUsername() + " "
+ object.getPassword());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
列印如下