- 相關(guān)推薦
java如何正確停止一個線程
導(dǎo)語:如何停止java的線程一直是一個開發(fā)多線程程序常遇到的一個問題。也有好多同學(xué)問過,所以今天在這里總結(jié)一下希望可以讓更多的人知道在java中如何安全的結(jié)束一個正在運(yùn)行的線程。一起來學(xué)習(xí)下吧:
1. 使用共享變量的方式
在這種方式中,之所以引入共享變量,是因為該變量可以被多個執(zhí)行相同任務(wù)的線程用來作為是否中斷的信號,通知中斷線程的執(zhí)行。
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();
thread.start();
sleep(3000); // 主線程延遲3秒
thread.exit = true; // 終止線程thread
thread.join();
System.out.println("線程退出!");
}
}
在上面代碼中定義了一個退出標(biāo)志exit,當(dāng)exit為true時,while循環(huán)退出,exit的默認(rèn)值為false。在定義exit時,使用了一個Java關(guān)鍵字volatile,這個關(guān)鍵字的目的是使exit同步,也就是說在同一時刻只能由一個線程來修改exit的值。
建議使用如下的方法來停止線程:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
2. 使用interrupt方法終止線程
如果一個線程由于等待某些事件的發(fā)生而被阻塞,又該怎樣停止該線程呢?
這種情況經(jīng)常會發(fā)生,比如當(dāng)一個線程由于需要等候鍵盤輸入而被阻塞,或者調(diào)用Thread.join()方法,或者Thread.sleep()方法,在網(wǎng)絡(luò)中調(diào)用ServerSocket.accept()方法,或者調(diào)用了DatagramSocket.receive()方法時,都有可能導(dǎo)致線程阻塞,使線程處于處于不可運(yùn)行狀態(tài)時,即使主程序中將該線程的共享變量設(shè)置為true,但該線程此時根本無法檢查循環(huán)標(biāo)志,當(dāng)然也就無法立即中斷。
這里我們給出的建議是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,因為該方法雖然不會中斷一個正在運(yùn)行的線程,但是它可以使一個被阻塞的線程拋出一個中斷異常,從而使線程提前結(jié)束阻塞狀態(tài),退出堵塞代碼。
class MyThread extends Thread {
volatile boolean stop = false;
public void run() {
while (!stop) {
System.out.println(getName() + " is running");
try {
sleep(1000);
}catch (InterruptedException e) {
System.out.println("week up from blcok...");
stop = true; // 在異常處理代碼中修改共享變量的狀態(tài)
}
}
System.out.println(getName() + " is exiting...");
}
}
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
System.out.println("Starting thread...");
m1.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " + m1.getName());
m1.stop = true; // 設(shè)置共享變量為true
m1.interrupt(); // 阻塞時退出阻塞狀態(tài)
Thread.sleep(3000); // 主線程休眠3秒以便觀察線程m1的中斷情況
System.out.println("Stopping application...");
}
}
注意:在Thread類中有兩個方法可以判斷線程是否通過interrupt方法被終止。一個是靜態(tài)的方法interrupted(),一個是非靜態(tài)的方法isInterrupted(),這兩個方法的區(qū)別是interrupted用來判斷當(dāng)前線是否被中斷,而isInterrupted可以用來判斷其他線程是否被中斷。
【java如何正確停止一個線程】相關(guān)文章:
java中如何停止線程08-14
如何創(chuàng)建并運(yùn)行Java線程10-01
如何使用java多線程08-23
淺談如何使用java多線程10-17
java Runnable接口如何創(chuàng)建線程09-11
Java 如何進(jìn)行線程同步05-19
java的多線程09-09
java多線程08-31
Java多線程的線程守護(hù)例子06-08