Java中如何優雅正確的終止線程

來源:互聯網
上載者:User

標籤:start   title   java   ring   exce   func   簡單   ted   例子   

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;        }  }

最後,運行結果,如下:

第1個線程建立第2個線程建立第3個線程建立--------------------------第3個線程終止第1個線程終止第2個線程終止

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

第一種:正在運行中終止

public class MyThread extends Thread {    public void run(){        super.run();        try {            for(int i=0; i<500000; i++){                if(this.interrupted()) {                    System.out.println("線程已經終止, for迴圈不再執行");                        throw new InterruptedException();                }                System.out.println("i="+(i+1));            }            System.out.println("這是for迴圈外面的語句,也會被執行");        } catch (InterruptedException e) {            System.out.println("進入MyThread.java類中的catch了。。。");            e.printStackTrace();        }    }}
public class Run {    public static void main(String args[]){        Thread thread = new MyThread();        thread.start();        try {            Thread.sleep(2000);            thread.interrupt();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

運行結果如下:

...i=203798i=203799i=203800線程已經終止, for迴圈不再執行進入MyThread.java類中的catch了。。。java.lang.InterruptedException    at thread.MyThread.run(MyThread.java:13)

第二種:阻塞狀態(sleep,wait等)終止

public class MyThread extends Thread {    public void run(){        super.run();        try {            System.out.println("線程開始。。。");            Thread.sleep(200000);            System.out.println("線程結束。");        } catch (InterruptedException e) {            System.out.println("在沉睡中被停止, 進入catch, 調用isInterrupted()方法的結果是:" + this.isInterrupted());            e.printStackTrace();        }    }}
線程開始。。。在沉睡中被停止, 進入catch, 調用isInterrupted()方法的結果是:falsejava.lang.InterruptedException: sleep interrupted    at java.lang.Thread.sleep(Native Method)    at thread.MyThread.run(MyThread.java:12)

從列印的結果來看, 如果在sleep狀態下停止某一線程,會進入catch語句,並且清除停止狀態值,使之變為false。

前一個實驗是先sleep然後再用interrupt()停止,與之相反的操作在學習過程中也要注意:

public class MyThread extends Thread {    public void run(){        super.run();        try {            System.out.println("線程開始。。。");            for(int i=0; i<10000; i++){                System.out.println("i=" + i);            }            Thread.sleep(200000);            System.out.println("線程結束。");        } catch (InterruptedException e) {             System.out.println("先停止,再遇到sleep,進入catch異常");            e.printStackTrace();        }    }}public class Run {    public static void main(String args[]){        Thread thread = new MyThread();        thread.start();        thread.interrupt();    }}

運行結果:

i=9998i=9999先停止,再遇到sleep,進入catch異常java.lang.InterruptedException: sleep interrupted    at java.lang.Thread.sleep(Native Method)    at thread.MyThread.run(MyThread.java:15)

Java中如何優雅正確的終止線程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.