多線程常見的三種實現方式


注意: 這只說明最常見的三種實現方式,並不說明線程池.

三種實現方案

  • 繼承Thread類的方式進行實現
  • 實現Runnable接口的方式進行實現
  • 利用Callable和Future接口方式實現

方案一:繼承Thread類

  • 定義一個MyThread繼承Thread
  • 在MyThread類中重寫run方法
  • 創建MyThread類的對象
  • 起動線程
public class Threadtest {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        //這里的代碼就是線程開啟之后要執行的代碼
        for (int i = 0; i < 100; i++) {
            System.out.println("線程開啟了:"+i);
        }
    }
}

為什么要重寫run()方法?

因為run方法是用來封裝被線程執行的代碼

run()方法和start()方法的區別

run():封裝線程執行的代碼,直接調用,相當於普通方法的調用,並沒有開啟線程
start():啟動線程;然后由JVM調用此線程的run方法

方案二:實現Runnable接口

  • 定義一個MyRunnable類實現Runnable接口 //這里可以選擇lambda表達式
  • 在MyRunnable類中重寫run()方法
  • 創建MyRunnable類的對象
  • 創建Thread類的對象,把MyRunnable對象作為構造方法的參數
  • 啟動線程
public class MyRunnableTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Runnable啟動線程的方式:"+i);
        }
    }
}

方案三:Callable和Future

  • 定義一個類MyCallable實現Callable接口
  • 在MyCallable類中重寫call()方法
  • 創建MyCallable類的對象
  • 創建Future的實現類FutureTask對象,把MyCallable對象作為構造方法的參數
  • 創建Thread類的對象,把FutureTask對象作為構造方法的參數
  • 啟動線程

*在調用get()方法,就可以獲取線程結束后的結果

public class MyCallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        //線程開啟之后,可以通過get方法獲得線程返回的數據
        //一定是要線程開啟之后
        String res = futureTask.get();
        System.out.println("返回的結果為:"+res);
    }
}

//這里的Callable是泛型,里面指定String是設定的返回值類型為String
class MyCallable implements Callable<String>{

    @Override
    public String call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("跟女孩表白次數:"+i);
        }
        return "OK";
    }
}

三種方式簡單對比

- 優點 缺點
實現Runnable,Callable接口 擴展性強,實現該接口的同時還可以繼承其他的類 編程相對復雜,不能直接使用Thread類中的方法
繼承Thread類 編程比較簡單,可以直接使用Thread類中的方法 可擴展性較差,不能繼承其他類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM