如何正確中斷 一個執行緒?
阿新 • • 發佈:2020-12-31
如何正確中斷 一個執行緒?
1、通過執行緒提供的方法
- interrupt
通過呼叫此方法,系統就會給當前執行緒打上一個中斷標記(true),預設為false,如果其他執行緒中呼叫當前執行緒中的此方法,表示告訴當前執行緒你可以停止了,當前執行緒也可以不理睬繼續執行 - isInterrupted
判斷當前執行緒是否被中斷,根據當前執行緒中斷標誌位,做相關的處理 - Thread.interrupted()
判斷執行緒是否被中斷,此方法是個靜態方法,跟isInterrupted 不同的是,在判斷的之後會重置中斷標記位為false
1.1 通過Thread 提供的方法來中斷操作(建議使用)
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//預設標誌位 為false
while (!isInterrupted()){
System.out.println(currentThread().getName()+"::::runing......." );
}
System.out.println("執行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt ();
上邊是個比較簡單的例子,如果當前執行緒執行體裡邊有阻塞方法會是什麼樣的情況:
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//預設標誌位 為false
while (!isInterrupted()){
try {
sleep(1000);
System.out.println(currentThread().getName()+"::::runing.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("執行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
輸入結果
TestCustomisInterrupted::::runing.......
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.example.socket.MyClass$1.run(MyClass.java:78)
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
會丟擲一箇中斷異常,並且把中斷標誌為重置為false,執行緒不會停止會一直執行,如果想讓程式繼續執行中斷操作可以在,異常裡邊繼續設定中斷操作
利用Thread.interrupted() 靜態方法判斷,如果發生中斷之後,會直接把中斷標記位設定為fasle
final Thread thread=new Thread("TestCustomisInterrupted"){
@Override
public void run() {
super.run();
//預設標誌位 為false
while (!Thread.interrupted()){
System.out.println(currentThread().getName()+"::::runing.......");
}
System.out.println("執行完成::::"+isInterrupted()); //true
}
};
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
執行完成::::false
2、通過執行緒自定義欄位去終止執行緒
class MyRunable implements Runnable{
boolean isRun=true;
public boolean isRun() {
return isRun;
}
public void setRun(boolean run) {
isRun = run;
}
@Override
public void run() {
while (isRun){
System.out.println("::::runing.......");
}
System.out.println("執行完成::::"+isRun); //true
}
}
MyRunable myRunable=new MyRunable();
new Thread(myRunable).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunable.setRun(false);
::::runing.......
::::runing.......
::::runing.......
::::runing.......
::::runing.......
執行完成::::false
使用自定義標記也可以來停止執行緒,那和執行緒提供的方法有什麼不一樣的呢?
加入我們的run方法邏輯中有阻塞方法時候
class Mythread extends Thread{
boolean isRun=true;
public boolean isRun() {
return isRun;
}
public void setRun(boolean run) {
isRun = run;
}
@Override
public void run() {
super.run();
while (isRun()){
try {
Thread.sleep(4000);
System.out.println("::::runing.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("執行完成::::"+isRun()); //true
}
}
Mythread mythread=new Mythread();
mythread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mythread.setRun(false);
加入sleep方法之後,發現線上程休眠的時候呼叫的mythread.setRun(false);
執行緒不會馬上停止,會等到休眠時間到了執行完run方法之後,才會停止
3、使用執行緒的 stop、suspend、resume 方法
以上三個是thread 提供的方法,但是現在被標註過期,不建議 使用,是因為使用以上方法,停止執行緒系統不會釋放執行緒所佔有的資源,因為沒有給執行緒釋放資源的機會和時間,會引起其他問題,所以不建議使用。