建立線程能夠說是併發知識中最基礎的操做了,JDK 提供的建立線程的方式,若是不包括經過線程池的話,目前有三種形式,它們分別是經過繼承 Thread 類,經過實現 Runable 接口,經過 FutureTask。以下圖所示java
下面整理了一下 3 種方法的具體使用與異同。多線程
class MyThread extends Thread { @Override public void run() { String threadName = getName(); for (int i = 0; i < 20; i++) { System.out.println("線程[" + threadName + "]運行開始,i = " + i + " time = " + new Date()); } } }
MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.start(); myThread2.start(); String threadName = Thread.currentThread().getName(); for (int i = 0; i < 20; i++) { System.out.println("線程[" + threadName + "]運行開始,i = " + i + " time = " + new Date()); }
總體流程以下:併發
這裏步驟比較簡單和清晰異步
class MyRunable implements Runnable { @Override public void run() { String threadName = Thread.currentThread().getName(); for (int i = 0; i < 20; i++) { System.out.println("線程[" + threadName + "]運行開始,i = " + i + " time = " + new Date()); } } }
MyRunable myRunable = new MyRunable(); new Thread(myRunable).start(); new Thread(myRunable).start(); String threadName = Thread.currentThread().getName(); for (int i = 0; i < 20; i++) { System.out.println("線程[" + threadName + "]運行開始,i = " + i + " time = " + new Date()); }
總體流程以下:ide
具體步驟以下:函數
class MyCallerTask implements Callable<string> { @Override public String call() throws Exception { System.out.println("執行任務開始"); Thread.sleep(3000); System.out.println("執行任務結束"); return "hello"; } }
// 建立異步任務 FutureTask<string> futureTask = new FutureTask<>(new MyCallerTask()); // 啓動線程 new Thread(futureTask).start(); System.out.println("其它操做"); try { // 等待任務執行完,並得到任務執行完的結果 String result = futureTask.get(); System.out.println(result); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
總體流程以下:線程
具體步驟以下:3d
經過上述的演示代碼,能夠看出這 3 種方法,其實各有優缺點code
經過代碼量與邏輯能夠明顯感受出來,第一種直接繼承 Thread 最方便,而且其它兩種到最後,仍是要依賴建立 Thread 才能實現。因此從方便及難易程度來看,能夠獲得以下結論: blog
經過演示代碼能夠看出,只有第一種是經過繼承,其它兩種是經過實現接口的形式。咱們都知道 JAVA 是不容許多繼承,可是能夠多實現。因此若是使用了第一種方法,就沒法再繼承別的類了。另外第一種把線程與線程任務冗餘在了一塊兒,不利於後期的維護。因此能夠獲得以下結論:
從代碼中能夠很容易看出,只有經過 FutureTask 的方式纔有返回值,另外兩種均沒有,因此得出以下結論
若是要用到返回值,那不用想,確定只能使用 FutureTask 的方法。若是對於返回值沒有要求,那Thread 與 Runable 都可,不過,考慮到可擴展性,最好使用 Runable 的形式。不過,話說回來,若是在真正項目中使用,綜合考慮,通常仍是最推薦經過線程池去建立。
> 本文由博客一文多發平臺 OpenWrite 發佈! </t></string></string></t>