Java建立線程的四種方式

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 的不足而設計的,可讓程序員跟蹤、獲取任務的執行狀況、計算結果java

  • 建立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。可應用於重發機制。
相關文章
相關標籤/搜索