【多執行緒】——停止執行緒的三種方式
阿新 • • 發佈:2019-02-12
前提
停止執行緒是在多執行緒開發時非常重要的方式,掌握執行緒的停止可以對執行緒的停止進行有效的處理。停止執行緒在Java中不像break那樣乾脆,而需要一些技巧性。
停止執行緒的方式有三種,分別展示一下
方式一
使用退出標識,使得執行緒正常退出,即當run方法完成後程序終止。
public void run() {
while(flag){
//do something
}
}
利用識別符號flag判定執行緒是否繼續執行。
方式二
使用stop強行中斷執行緒(此方法為作廢過期方法),不推薦使用,暴力終止,可能使一些清理性的工作得不到完成。還可能對鎖定的內容進行解鎖,容易造成資料不同步的問題。
方式三
使用interrupt方法中斷執行緒。
在Thread.java類裡提供了兩種方法判斷執行緒是否為停止的。
this.interrupted():測試當前執行緒是否已經中斷(靜態方法)。如果連續呼叫該方法,則第二次呼叫將返回false。在api文件中說明interrupted()方法具有清除狀態的功能。執行後具有將狀態標識清除為false的功能。
this.isInterrupted():測試執行緒是否已經中斷,但是不能清除狀態標識。
執行緒停止——拋異常法
public class MyThread4 extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 50000; i++) {
if (this.isInterrupted()) {
System.out.println( "執行緒已經結束,我要退出" );
break;
}
System.out.println( "i=" + (i + 1) );
}
System.out.println( "我是for下面的語句,我被執行說明執行緒沒有真正結束" );
}
}
public static void main(String[] args) {
try {
MyThread4 myThread4 = new MyThread4();
myThread4.start();
Thread.sleep( 20);
myThread4.interrupt();
} catch (InterruptedException e) {
System.out.println( "main catch" );
e.printStackTrace();
}
}
根據列印結果發現for後面的內容依舊會執行,為了解決這種問題,可以採用拋異常的方式,或return的方式終止執行緒。一般推薦拋異常的方式,這樣才能使得執行緒停止得以擴散。
public class MyThread4 extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 50000; i++) {
if (this.isInterrupted()) {
System.out.println( "執行緒已經結束,我要退出" );
// return;
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();
}
}
}
在沉睡中停止
先sleep,後interrupt
@Override
public void run() {
super.run();
try {
System.out.println( "begin run" );
Thread.sleep( 500 );
System.out.println( "begin end" );
} catch (InterruptedException e) {
System.out.println("在沉睡中終止");
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
MyThread5 thread5 = new MyThread5();
thread5.start();
Thread.sleep( 20 );
thread5.interrupt();
} catch (InterruptedException e) {
System.out.println( "main catch" );
e.printStackTrace();
}
}
從列印結果看,sleep狀態下停止某一個執行緒,會進入catch語句,並清除狀態值,變成false
先interrupt後sleep
try {
for (int i = 0; i < 10000; i++) {
System.out.println( "i=" +(i + 1) );
}
System.out.println( "run begin" );
Thread.sleep( 200 );
System.out.println( "run end" );
} catch (InterruptedException e) {
System.out.println( "先停止,後sleep" );
e.printStackTrace();
}
public static void main(String[] args) {
MyThread5 thread5 = new MyThread5();
thread5.start();
thread5.interrupt();
}
任務執行完成後,才丟擲異常!
總結
很基礎的內容,多加積累!