實現Runnable接口
/*實現Runnable接口*/ private class UseRun implements Runnable{ @Override public void run() { System.out.println("I am implements Runnable"); } public static void main(String[] args) { UseRun useRun = new UseRun(); new Thread(useRun).start(); } }
實現Callable接口,允許有返回值
/*實現Callable接口,允許有返回值*/ private static class UseCall implements Callable<String>{ @Override public String call() throws Exception { System.out.println("I am implements Callable"); return "CallResult"; } public static void main(String[] args) { //第一步,先new一個類 UseCall useCall = new UseCall(); //第二步,用FutureTask類包裝下,注意:FutureTask類繼承了Runnable接口 FutureTask<String> futureTask = new FutureTask<>(useCall); //第三步,啟動 new Thread(futureTask).start(); //第四步,得到線程返回的結果,注意這里是阻塞式的。必須執行完線程才能拿到結果 System.out.println(futureTask.get()); } }
繼承Thread類創建線程
public class MyThread extends Thread{//繼承Thread類 public void run(){ //重寫run方法 } } public class Main { public static void main(String[] args){ new MyThread().start();//創建並啟動線程 } }
如何讓線程停止?
怎么樣才能讓Java里的線程安全停止工作呢?
線程自然終止:自然執行完或拋出未處理異常,
stop() (停止線程),resume() (繼續執行線程), suspend() (掛起線程 ) 已不建議使用,stop()會導致線程不會正確釋放資源,suspend()容易導致死鎖。
java線程是協作式,而非搶占式
- 調用一個線程的interrupt() 方法中斷一個線程,並不是強行關閉這個線程,只是跟這個線程打個招呼,將線程的中斷標志位置為true,線程是否中斷,由線程本身決定。
- isInterrupted() 判定當前線程是否處於中斷狀態。
- static方法interrupted() 判定當前線程是否處於中斷狀態,同時中斷標志位改為false。
-
方法里如果拋出InterruptedException,線程的中斷標志位會被復位成false,如果確實是需要中斷線程,要求我們自己在catch語句塊里再次調用interrupt()。
package com.kakaluote.multi_threaddemo.Multi_001.safeend; /** * @Description * @auther 劉中華 * @create 2019-04-03 21:44 * * 測試的目的:我們起一個線程,想中途把它關閉,一般使用變量flag=trun/false的方法。關閉就變成false,結束循環,這樣關閉時不嚴謹的。 * 我們一般采用isInterrupted()的方法,這個方法是判斷當前線程是否掛起。掛起返回true,否則返回false。 * 發現的問題:當我們調用中斷線程之后,發現線程還在跑???為什么呢? * 樓主發現線程還在運行證明不是線程結束造成的,對線程的interrupt是對線程處在sleep,wait,join狀態的時候才起作用。 * InterruptException不interrupt()方法拋出的,interrupt()只改變線程的中斷狀態, * sleep,wait,join的內部會不停的檢查線程中斷狀態,如果它們檢查到線程處於中斷狀態,就拋出異常中斷線程。 * 如果你的線程不處於這3個狀態中,調用interrupt不會中斷線程,或者說不會馬上中斷線程, * 如果后面的代碼有讓線程進入上面3個狀態的其中一個,線程會馬上拋出InterruptException而中斷, * 因為你之前的interrupt()調用改變了線程的內部狀態。 */ public class EndRunnable { private static class UseRunnable implements Runnable{ @Override public void run() { String threadName = Thread.currentThread().getName(); while(!Thread.currentThread().isInterrupted()) { //讓線程拋出InterruptedException異常。測試 當InterruptedException異常的時候會把isInterrupted() 設置為false,我們需要再次調用下中斷 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } System.out.println(threadName+" is run!"); } System.out.println(threadName+" interrput flag is " +Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException { UseRunnable useRunnable = new UseRunnable(); Thread endThread = new Thread(useRunnable,"endThread"); endThread.start(); Thread.sleep(2); endThread.interrupt(); } }