(一)執行緒建立與執行
Java併發程式設計之美->讀書筆記
Java 中有3種執行緒建立方式,
1,分別為實現 Runnable 介面的 run 方法,
2,繼承 Thread並重寫 run 方法,
3,使用 FutureTask 方式 首先看繼承Thread類方式實現。
繼承Thread類並重寫run方法
//繼承Thread類並重寫run方法 public static class MyThread extends Thread { @Override public void run() { System.out.println("I am a children"); } } public static void main(String[] args) { //建立執行緒 MyThread myThread = new MyThread(); //啟動執行緒 myThread.start(); }
如上程式碼中的MyThread類繼承了Thread類,並重寫了run()方法。
在main函式裡面建立了一個MyThread的例項,然後呼叫該例項的start方法啟動了執行緒。
需要注意的是,當建立完thread物件後該執行緒並沒有被啟動執行,知道呼叫了start方法後才真正啟動了執行緒。
其實呼叫start方法後執行緒並沒有馬上執行而是處於就緒狀態,這個就緒狀態是指該執行緒已經獲取了除CPU資源外的其他資源,等待獲取CPU資源後才會真正處於執行狀態。
一旦run方法執行完畢,該執行緒就處於終止狀態 * * 使用繼承方式的好處是,在run()方法內獲取當前執行緒直接使用this就可以了,無需使用Thread.currentThread()方法;
不好的地方是java不支援多繼承,如果繼承了Thread類,那麼就不能再繼承其他類。
另外任務與程式碼沒有分離,當多個執行緒執行一樣的任務時需要多份任務程式碼,而Runnable則沒有這個限制。
實現Runnable介面的run方法方式
public static class RunnableTask implements Runnable{ @Override public void run() { System.out.println("!222222"); } } public static void main (String[] args){ RunnableTask task = new RunnableTask(); new Thread(task).start(); new Thread(task).start(); }
如上面程式碼所示,兩個執行緒共用一個task程式碼邏輯,如果需要,可以給RunnableTask新增引數進行任務區分。
另外,RunnableTask可以繼承其他類。但是上面介紹的兩種方式都有一個缺點,就是任務沒有返回值。
使用FutureTask的方式
//建立任務類,類似Runnable public static class CallerTask implements Callable<String> { @Override public String call() throws Exception { return "hello"; } } public static void main(String[] args) throws InterruptedException{ //建立非同步任務 Future<String> futureTask = new FutureTask<>(new CallerTask()); //啟動執行緒 new Thread((Runnable) futureTask).start(); try { String result = futureTask.get(); System.out.println(result); } catch (ExecutionException e) { e.printStackTrace(); } }
如上程式碼中的CallerTask類實現了Callable介面的call()方法。
在main函式內首先建立了一個FutrueTask物件(建構函式為CallerTask的例項),然後使用建立的FutrueTask物件作為任務建立了一個執行緒並且啟動它,
最後通過futureTask.get()等待任務執行完畢並返回結果
小結:使用繼承方式的好處是方便傳參,你可以在子類裡面新增成員變數,通過set方法設定引數或者通過建構函式進行傳遞,
而如果使用Runnable方式,則只能使用主執行緒裡面被宣告為final的變數。
不好的地方是java不支援多繼承,如果繼承了Thread類,那麼子類不能再繼承其他類,
而Runnable則沒有這個限制。前兩種方式都沒辦法拿到任務的返回結果,但是Futuretask方式可以.