java如何正確停止一個線程

來源:互聯網
上載者:User

標籤:

Thread類中有start(), stop()方法,不過stop方法已經被廢棄掉。

平時其實也有用過,共用一個變數,相當於標誌,不斷檢查標誌,判斷是否退出線程

如果有阻塞,需要使用Thread的interrupt()方中斷阻塞,線程開始檢查標誌(PS:拋出異常不會退出迴圈)

------------------------------------------------------------我是copy分割線----------------------------------------------

原出處:http://blog.163.com/xh_ding/blog/static/193903289201341685931689

如何停止java的線程一直是一個開發多線程程式常遇到的一個問題。也有好多人問過我,所以今天在這裡總結一下希望可以讓更多的人知道在java中如何安全的結束一個正在啟動並執行線程。

在Java的多線程編程中,java.lang.Thread類型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。通過這些方法,我們可以對線程進行方便的操作,但是這些方法中,只有start()方法得到了保留。在JDK協助文檔以及Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中都講解了捨棄這些方法的原因。那麼,我們究竟應該如何停止線程呢?這裡我們介紹兩種方法:  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();         thread.start();         sleep(3000); // 主線程延遲3秒         thread.exit = true;  // 終止線程thread         thread.join();         System.out.println("線程退出!");     } } 在上面代碼中定義了一個退出標誌exit,當exit為true時,while迴圈退出,exit的預設值為false。在定義exit時,使用了一個Java關鍵字volatile,這個關鍵字的目的是使exit同步,也就是說在同一時刻只能由一個線程來修改exit的值。 在《Why Are Thread.stop, Thread.suspend,Thread.resume and Runtime.runFinalizersOnExit Deprecated?》中,建議使用如下的方法來停止線程:  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方法終止線程  如果一個線程由於等待某些事件的發生而被阻塞,又該怎樣停止該線程呢?這種情況經常會發生,比如當一個線程由於需要等候鍵盤輸入而被阻塞,或者調用Thread.join()方法,或者Thread.sleep()方法,在網路中調用ServerSocket.accept()方法,或者調用了DatagramSocket.receive()方法時,都有可能導致線程阻塞,使線程處於處於不可運行狀態時,即使主程式中將該線程的共用變數設定為true,但該線程此時根本無法檢查迴圈標誌,當然也就無法立即中斷。這裡我們給出的建議是,不要使用stop()方法,而是使用Thread提供的interrupt()方法,因為該方法雖然不會中斷一個正在啟動並執行線程,但是它可以使一個被阻塞的線程拋出一個中斷異常,從而使線程提前結束阻塞狀態,退出堵塞代碼。 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; // 在異常處理代碼中修改共用變數的狀態}}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; // 設定共用變數為truem1.interrupt(); // 阻塞時退出阻塞狀態Thread.sleep(3000); // 主線程休眠3秒以便觀察線程m1的中斷情況System.out.println("Stopping application...");}} 注意:在Thread類中有兩個方法可以判斷線程是否通過interrupt方法被終止。一個是靜態方法interrupted(),一個是非靜態方法isInterrupted(),這兩個方法的區別是interrupted用來判斷當前線是否被中斷,而isInterrupted可以用來判斷其他線程是否被中斷。

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.