java如何正確停止一個執行緒
導語:如何停止java的執行緒一直是一個開發多執行緒程式常遇到的一個問題。也有好多同學問過,所以今天在這裡總結一下希望可以讓更多的人知道在java中如何安全的結束一個正在執行的.執行緒。一起來學習下吧:
1. 使用共享變數的方式
在這種方式中,之所以引入共享變數,是因為該變數可以被多個執行相同任務的執行緒用來作為是否中斷的訊號,通知中斷執行緒的執行。
public class ThreadFlag extends Thread
{
public volatile boolean exit = false;
public void run()
{
while (!exit);
}
public static void main(String[] args) throws Exception
{
ThreadFlag thread = new ThreadFlag();
t();
sleep(3000); // 主執行緒延遲3秒
= true; // 終止執行緒thread
();
tln("執行緒退出!");
}
}
在上面程式碼中定義了一個退出標誌exit,當exit為true時,while迴圈退出,exit的預設值為false。在定義exit時,使用了一個Java關鍵字volatile,這個關鍵字的目的是使exit同步,也就是說在同一時刻只能由一個執行緒來修改exit的值。
建議使用如下的方法來停止執行緒:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = entThread();
while (blinker == thisThread) {
try {
p(interval);
} catch (InterruptedException e){
}
repaint();
}
}
2. 使用interrupt方法終止執行緒
如果一個執行緒由於等待某些事件的發生而被阻塞,又該怎樣停止該執行緒呢?
這種情況經常會發生,比如當一個執行緒由於需要等候鍵盤輸入而被阻塞,或者呼叫()方法,或者p()方法,在網路中呼叫pt()方法,或者呼叫了ive()方法時,都有可能導致執行緒阻塞,使執行緒處於處於不可執行狀態時,即使主程式中將該執行緒的共享變數設定為true,但該執行緒此時根本無法檢查迴圈標誌,當然也就無法立即中斷。
這裡我們給出的建議是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,因為該方法雖然不會中斷一個正在執行的執行緒,但是它可以使一個被阻塞的執行緒丟擲一箇中斷異常,從而使執行緒提前結束阻塞狀態,退出堵塞程式碼。
class MyThread extends Thread {
volatile boolean stop = false;
public void run() {
while (!stop) {
tln(getName() + " is running");
try {
sleep(1000);
}catch (InterruptedException e) {
tln("week up from blcok...");
stop = true; // 在異常處理程式碼中修改共享變數的狀態
}
}
tln(getName() + " is exiting...");
}
}
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
tln("Starting thread...");
t();
p(3000);
tln("Interrupt thread...: " + ame());
= true; // 設定共享變數為true
rrupt(); // 阻塞時退出阻塞狀態
p(3000); // 主執行緒休眠3秒以便觀察執行緒m1的中斷情況
tln("Stopping application...");
}
}
注意:在Thread類中有兩個方法可以判斷執行緒是否通過interrupt方法被終止。一個是靜態的方法interrupted(),一個是非靜態的方法isInterrupted(),這兩個方法的區別是interrupted用來判斷當前線是否被中斷,而isInterrupted可以用來判斷其他執行緒是否被中斷。