Java中如何正確而優雅的終止執行中的執行緒
阿新 • • 發佈:2018-12-24
Java中終止執行緒的方式主要有三種:
1、使用stop()方法,已被棄用。原因是:stop()是立即終止,會導致一些資料被到處理一部分就會被終止,而使用者並不知道哪些資料被處理,哪些沒有被處理,產生了不完整的“殘疾”資料,不符合完整性,所以被廢棄。So, forget it!
2、使用volatile標誌位
看一個簡單的例子:
首先,實現一個Runnable介面,在其中定義volatile標誌位,在run()方法中使用標誌位控制程式執行。
然後,在main()方法中建立執行緒,在合適的時候,修改標誌位,終止執行中的執行緒。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() + "個執行緒終止"); } }
最後,執行結果,如下: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();
}
}
執行結果: