一.中止線程會帶來什麼?安全
對於單線程中,中止單線程就是直接使用關鍵字return或者break,可是在中止多線程時是讓線程在完成任務前去開啓另一條線程,必須放棄當前任務,而這個過程是不可預測,因此必須去作好防備。性能優化
二.認識中止線程的幾個方法多線程
2.1三個被棄用的方法架構
stop()、suspend()、resume()。併發
stop()方法被棄用的緣由:不管線程執行到了什麼位置,一旦被stop就會被立刻強制中斷,而且釋放線程全部持有鎖對象,根本就沒有安全性。分佈式
suspend()和resume()這一對爛兄爛弟,由於只有其餘線程調用resume這個方法時他纔會釋放suspend這個方法的鎖,這樣就極易形成死鎖。ide
2.2三個名字差很少的方法微服務
interrupt()中斷線程、interrupted()判斷當前線程是否中止、isInterrupted()判斷線程是否中止。高併發
首先來介紹一下其中兩個名字最相近的:interrupted()、isInterrupted()方法,這兩個方法是用來測試線程是否被中斷的。源碼分析
來看一下原碼:
isInterrupted():
public boolean isInterrupted() { return isInterrupted(false); }
interrupted():
public static boolean interrupted() { return currentThread().isInterrupted(true); }
能夠明顯看出interrupted()方法是靜態的,而isInterrupted()是非靜態的,但都是返回線程是否被中斷。
下面咱們來作一個測試,代碼以下:
public class Is_Interrupt extends Thread{ @Override public void run(){ for(int i=0;i<1000;i++){ System.out.println("當前i的值爲:"+i); } } public static void main(String[] args) { Is_Interrupt is_interrupt=new Is_Interrupt(); is_interrupt.start(); is_interrupt.interrupt();//中斷線程 System.out.println("線程是否已經暫停?"+is_interrupt.interrupted()); } }
輸出結果爲:
發現線程沒有中止。
可是這裏面還有一個線程就是main線程,而interrupted()返回的就是當前線程的中斷狀態,那麼執行這個方法的就是main線程,而main線程此時固然沒有中斷。
咱們將interrupted()方法改成isInterrupted()試試效果,代碼以下:
public class Is_Interrupt extends Thread{ @Override public void run(){ for(int i=0;i<1000;i++){ System.out.println("當前i的值爲:"+i); } } public static void main(String[] args) { Is_Interrupt is_interrupt=new Is_Interrupt(); is_interrupt.start(); is_interrupt.interrupt();//中斷線程 System.out.println("線程是否已經暫停?"+is_interrupt.isInterrupted()); } }
結果以下:
說明線程是已經中止了的,只不過咱們使用錯了一個方法而已判斷成了main線程的狀態。
總結:isInterrupted方法是返回調用對象的中斷狀態,而靜態方法interrupted是返回當前線程的中斷狀態。
既然瞭解了這個誤區之後咱們再來看看下面的代碼:
public class InterruptText extends Thread{ public static void main(String[] args) { System.out.println("main線程啓動!"); System.out.println( Thread.interrupted());//判斷當前線程是否中斷 System.out.println(currentThread().isInterrupted());//經過currentThread().isInterrupted()一樣也能夠達到相同的目的,在單線程中 } }
輸出:
這個是沒有問題的。
那麼咱們屢次調用這個interrupted方法呢?
public class InterruptText extends Thread{ public static void main(String[] args) { System.out.println("main線程啓動!"); currentThread().interrupt();//中斷main線程 System.out.println( Thread.interrupted());//判斷當前main線程是否中斷 System.out.println( Thread.interrupted());//再一次判斷當main前線程是否中斷 } }
結果:
按照常理應該兩次返回ture,可是爲何變成了第二次變成了false了呢?
其實interrupted就是在清除狀態,你兩次調用固然會將true變成flase可是他仍是中斷狀態,可是isInterrupted是不清除的。
interrupt()方法:中斷線程
三.中止線程
3.1經過異常來暫停線程
首先來看一段代碼:
public class InterruptText extends Thread{ @Override public void run(){ try { for (int i = 0; i < 100000; i++) { if (currentThread().isInterrupted()) {//若是線程中斷 throw new InterruptedException();//拋出異常 } else { System.out.println(i); } } System.out.println("線程沒有終止"); }catch (InterruptedException e){ e.printStackTrace(); } } public static void main(String[] args) throws Exception { InterruptText interruptText=new InterruptText(); interruptText.start(); Thread.sleep(100); interruptText.interrupt(); } }
結果:
異常中止方法的策略就是:在遇到中斷時,拋出異常,撲捉異常。
3.2在睡眠中中斷線程
代碼以下:
public class InterruptText2 extends Thread { @Override public void run(){ try { Thread.sleep(10000);//線程睡眠 } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { InterruptText2 interruptText2=new InterruptText2(); interruptText2.start();//開啓線程,可是線程處於睡眠狀態 interruptText2.interrupt();//在睡眠狀態中斷線程 } }
結果爲:
3.3線程讓步
方法:yield(),當前線程放棄全部的資源,去執行其餘的任務。可是放棄資源的時間不能夠預判的。
3.4守護線程
守護線程的定義:守護線程是一種特殊的線程,區別於非守護線程,當程序中不存在非守護線程時,守護線程退出,程序退出。
設置守護線程:setDaemon(),參數爲ture則該線程爲守護線程。
在此我向你們推薦一個架構學習交流羣。交流學習羣號874811168 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多