1. 程式人生 > >Java中如何正確而優雅的終止執行中的執行緒

Java中如何正確而優雅的終止執行中的執行緒

Java中終止執行緒的方式主要有三種:

1、使用stop()方法,已被棄用。原因是:stop()是立即終止,會導致一些資料被到處理一部分就會被終止,而使用者並不知道哪些資料被處理,哪些沒有被處理,產生了不完整的“殘疾”資料,不符合完整性,所以被廢棄。So, forget it!

2、使用volatile標誌位

看一個簡單的例子:

首先,實現一個Runnable介面,在其中定義volatile標誌位,在run()方法中使用標誌位控制程式執行。

public class MyRunnable implements Runnable {

	//定義退出標誌,true會一直執行,false會退出迴圈
	//使用volatile目的是保證可見性,一處修改了標誌,處處都要去主存讀取新的值,而不是使用快取
	public volatile boolean flag = true;

	public void run() {
		System.out.println("第" + Thread.currentThread().getName() + "個執行緒建立");
		
		try {
			Thread.sleep(1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		//退出標誌生效位置
		while (flag) {
		}
		System.out.println("第" + Thread.currentThread().getName() + "個執行緒終止");
	}
}
然後,在main()方法中建立執行緒,在合適的時候,修改標誌位,終止執行中的執行緒。
public class TreadTest {
	public static void main(String[] arg) throws InterruptedException {
		MyRunnable runnable = new MyRunnable();
		
		//建立3個執行緒
		for (int i = 1; i <= 3; i++) {
			Thread thread = new Thread(runnable, i + "");
			thread.start();
		}
		//執行緒休眠
		Thread.sleep(2000L);
		System.out.println("——————————————————————————");
		//修改退出標誌,使執行緒終止
		runnable.flag = false;	
	}
}
最後,執行結果,如下:


3、使用interrupt()中斷的方式,注意使用interrupt()方法中斷正在執行中的執行緒只會修改中斷狀態位,可以通過isInterrupted()判斷。如果使用interrupt()方法中斷阻塞中的執行緒,那麼就會丟擲InterruptedException異常,可以通過catch捕獲異常,然後進行處理後終止執行緒。有些情況,我們不能判斷執行緒的狀態,所以使用interrupt()方法時一定要慎重考慮。

看一個簡單的例子(中斷執行中的執行緒):

public class MyRunnable2 implements Runnable{
	
	public void run(){
		System.out.println(Thread.currentThread().getName() + " 執行緒建立");
		try {
			Thread.sleep(1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//執行時的執行緒被中斷後,只會修改中斷標記,不會丟擲異常
		while(Thread.currentThread().isInterrupted()){
			
		}
		System.out.println(Thread.currentThread().getName() + " 執行緒被中斷");
	}

}
public class TreadTest {
	public static void main(String[] arg) throws InterruptedException {
		Runnable runnable = new MyRunnable2();
		
		//建立3個執行緒
		Thread thread1 = new Thread(runnable, "1");
		Thread thread2 = new Thread(runnable, "2");
		Thread thread3 = new Thread(runnable, "3");
		thread1.start();
		thread2.start();
		thread3.start();
		
		//執行緒休眠
		Thread.sleep(2000L);
		
		//修改退出標誌,使執行緒終止
		thread1.interrupt();
		thread2.interrupt();
		thread3.interrupt();
	}
}
執行結果: