Java基礎:執行緒的三種建立方式

救苦救难韩天尊發表於2024-07-04

一、繼承Thread類

  1. 定義一個類繼承執行緒類Thread
  2. 重寫run()方法
  3. 建立執行緒物件
  4. 呼叫執行緒物件的start()方法建立執行緒

Thread類的常用API

  • setName(String name):給執行緒取名字
  • getName():獲取執行緒的名字
  • public static Thread currentThread():獲取當前執行緒物件,這個程式碼在哪個執行緒中就獲取哪個執行緒物件
  • public static void sleep(long time):讓當前執行緒休眠多少毫秒再繼續執行

優點:

  • 編碼簡單

缺點:

  • 執行緒類已經繼承Thread就無法繼承其他類了,功能無法透過繼承擴充(單繼承的侷限性)

二、實現Runable介面

  1. 定義一個執行緒任務類實現Runable介面
  2. 重寫run()方法
  3. 建立執行緒任務物件
  4. 把執行緒任務物件包裝成執行緒物件
  5. 呼叫執行緒物件的start()方法啟動執行緒
class MyRunable implements Runnable{

    @Override
    public void run() {
        System.out.println("hello runable");
    }
}
public static void main(String[] args) {
    MyRunable target = new MyRunable();
    Thread t = new Thread(target);
    t.start();
}

優點:

  • 避免了Java單繼承的侷限性
  • 同一個任務物件可以被包裝成多個執行緒物件
  • 適合多個執行緒去共享同一個資源
  • 實現解耦,執行緒任務程式碼可以被多個執行緒共享,執行緒任務程式碼和執行緒獨立
  • 執行緒池只能放入實現Runable和Callable介面的執行緒任務,不能直接放入繼承Thread類的執行緒物件

缺點

  • 編碼複雜(其實還好啦)

匿名內部類的寫法:

Runnable target = new Runnable() {
    @Override
    public void run() {
        System.out.println("匿名內部類寫法");
    }
};
Thread t = new Thread(target);
t.start();

//簡化
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("匿名內部類寫法");
    }
}).start();

//再簡化
new Thread(() -> System.out.println("匿名內部類寫法")).start();

三、實現Callable介面

  1. 定義一個執行緒任務類實現Callable介面,申明執行緒執行的結果型別
  2. 重寫執行緒任務類的call方法,這個方法可以直接返回執行結果
  3. 建立一個Callable的執行緒任務物件
  4. 把執行緒任務物件包裝成一個未來任務物件
  5. 把未來任務物件包裝成執行緒物件
  6. 呼叫start()方法啟動執行緒
//1.定義一個執行緒任務類實現Callable介面,申明執行緒執行的結果型別
class MyCallable implements Callable<String>{

    //2.重寫執行緒任務類的call方法,這個方法可以直接返回執行結果
    @Override
    public String call() throws Exception {
        System.out.println("hello callable");
        return "success";
    }
}
//3.建立一個Callable的執行緒任務物件
Callable<String> call = new MyCallable();
//4.把執行緒任務物件包裝成一個未來任務物件
//-- 未來任務物件其實就是一個Runable物件,這樣就可以被包裝成執行緒物件
//-- 未來任務物件可以線上程執行完畢後得到執行緒執行結果
FutureTask<String> future = new FutureTask<>(call);

//5.把未來任務物件包裝成執行緒物件
Thread t = new Thread(future);
t.start();

//獲取執行緒執行結果,如果執行緒還沒執行完,讓出CPU等執行緒執行完再來去結果
try {
    String res = future.get();
    System.out.println(res);
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}

優點:

  • 擁有所有Runable的優點
  • 能直接得到執行緒執行的結果

缺點:

  • 編碼複雜

相關文章