Java創建執行緒的四種方式

  • 2019 年 11 月 8 日
  • 筆記

Java創建執行緒的四種方式

1.繼承Thread類創建執行緒

  • 定義Thread類的子類,並重寫該類的run方法,run()方法的內容就是該執行緒執行的內容
  • 創建Thread子類的實例,即創建了執行緒對象。
  • 調用執行緒對象的start()方法來啟動該執行緒。
    程式碼演示
public class MyThread extends Thread {        @Override      public void run() {          // 執行業務邏輯      }        public static void main(String[] args) {          MyThread myThread = new MyThread();          myThread.start();      }  }

2.通過Runnable介面創建執行緒類

  • 定義runnable介面的實現類,並重寫該介面的run()方法,該run()方法的方法體同樣是該執行緒的執行緒執行體。
  • 創建 Runnable實現類的實例,並依此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的執行緒對象。
  • 調用執行緒對象的start()方法來啟動該執行緒。
    程式碼演示
public class MyRunnable implements Runnable {      @Override      public void run() {          // 執行業務邏輯      }        public static void main(String[] args) {          MyRunnable myRunnable = new MyRunnable();          Thread thread = new Thread(myRunnable);          thread.start();      }  }

3.使用Callable介面和FutureTask類實現創建有返回結果的執行緒

FutureTask 的出現是為了彌補 Thread 的不足而設計的,可以讓程式設計師跟蹤、獲取任務的執行情況、計算結果

  • 創建Callable介面的實現類,並實現call()方法,該call()方法將作為執行緒執行體,並且有返回值。
  • 創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對- 象的call()方法的返回值。
  • 使用FutureTask對象作為Thread對象的target創建並啟動新執行緒。
  • 調用FutureTask對象的get()方法來獲得子執行緒執行結束後的返回值。
    程式碼演示
public class MyCallable implements Callable<Integer>{      @Override      public Integer call() throws Exception {          System.out.println("子執行緒開始計算");          Thread.sleep(2000);          System.out.println("子執行緒結束計算");          return 100 * 100;      }        public static void main(String[] args) throws ExecutionException, InterruptedException {          // 實例化Callable對象          MyCallable myCallable = new MyCallable();          // 使用FutureTask包裝          FutureTask<Integer> futureTask = new FutureTask<>(myCallable);          // 創建一個執行緒執行任務          Thread thread = new Thread(futureTask);          thread.start();          Thread.sleep(1000);          System.out.println("主執行緒執行");          // 使用get()方法會阻塞主執行緒,直到子執行緒執行完成返回結果          int result = futureTask.get();          System.out.println("子執行緒計算結果: " + result);      }    }

執行結果

子執行緒開始計算  主執行緒執行  子執行緒結束計算  子執行緒計算結果: 10000

4.使用執行緒池創建執行緒

為什麼要使用執行緒池呢?
當不是執行一次性任務的時候,如果不使用執行緒池,那麼就要頻繁的創建和銷毀執行緒,這是一個比較消耗資源的操作,使用執行緒池可以靈活的調整執行緒資源的佔用,防止消耗過多的記憶體
在Java中已經提供了ExecutorSerice、Executors等工具類為我們快速的創建執行緒池
常用的常見執行緒的方法有

  • Executors.newFixedThreadPool(int nThreads) --- 創建固定執行緒數量的執行緒池
  • Executors.newSingleThreadPool() --- 創建只包含一個執行緒的執行緒池
  • Executors.newCachedThreadPool() --- 創建一個可快取的執行緒池。如果執行緒池的當前規模超過了處理需求時,那麼就會回收部分空閑的執行緒(根據空閑時間來回收),當需求增加時,此執行緒池又可以智慧的添加新執行緒來處理任務。此執行緒池不會對執行緒池大小做限制,執行緒池大小完全依賴於作業系統(或者說JVM)能夠創建的最大執行緒大小。
  • Executors.newScheduledThreadPool() --- 創建了一個固定長度的執行緒池,而且以延遲或定時或周期的方式來執行任務,類似於Timer。可應用於重發機制。

Tags: