首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 線程三種實現方式:繼承 Thread、實現 Runnable、ExecutorService+Callable+Future

     編輯:Java 綜合教學

Java 線程三種實現方式:繼承 Thread、實現 Runnable、ExecutorService+Callable+Future

Java 創建線程有三種主流方式,本文對比優缺點,並給出生產環境推薦的「線程池 + Callable」完整範例。

方式一:繼承 Thread

public class MultiThread1 extends Thread {
    public void run() {
        for (int i = 0; i < 7; i++)
            System.out.println("name:" + this.getName() + " i:" + i);
    }
    public static void main(String[] args) {
        MultiThread1 tA = new MultiThread1(); tA.setName("AA");
        MultiThread1 tB = new MultiThread1(); tB.setName("BB");
        tA.start(); tB.start();
    }
}

缺點:單繼承限制,線程對象與任務耦合,無返回值,難以管理生命週期。

方式二:實現 Runnable

public class MyRunnable implements Runnable {
    private String name;
    public void run() {
        for (int i = 0; i < 10; i++)
            System.out.println("name:" + this.getName() + " i:" + i);
    }
    public static void main(String[] args) {
        MyRunnable mA = new MyRunnable(); mA.setName("AA");
        MyRunnable mB = new MyRunnable(); mB.setName("BB");
        new Thread(mA).start(); new Thread(mB).start();
    }
}

優點:任務與線程分離,支援多線程共享同一任務實例,避開單繼承。缺點:仍無返回值,手動管理線程啟動/停止。

方式三:ExecutorService + Callable + Future(推薦)

JDK 1.5 引入,支援返回值、異常傳播、線程池復用、超時控制。

import java.util.concurrent.*;
import java.util.*;

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("----程序開始運行----");
        Date date1 = new Date();
        int taskSize = 5;

        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        List<Future<Object>> list = new ArrayList<>();

        for (int i = 0; i < taskSize; i++) {
            Callable<Object> c = new MyCallable(i + " ");
            Future<Object> f = pool.submit(c);
            list.add(f);
        }
        pool.shutdown();

        for (Future<Object> f : list) {
            System.out.println(">>>" + f.get().toString());
        }
        Date date2 = new Date();
        System.out.println("----程序結束運行----,耗時 " + (date2.getTime() - date1.getTime()) + " 毫秒");
    }
}

class MyCallable implements Callable<Object> {
    private String taskNum;
    MyCallable(String taskNum) { this.taskNum = taskNum; }
    public Object call() throws Exception {
        System.out.println(">>>" + taskNum + "任務啟動");
        Date d1 = new Date();
        Thread.sleep(1000);
        Date d2 = new Date();
        long time = d2.getTime() - d1.getTime();
        System.out.println(">>>" + taskNum + "任務終止");
        return taskNum + "任務返回運行結果,耗時 " + time + " 毫秒";
    }
}

三方式對比總結

維度繼承 Thread實現 RunnableExecutorService+Callable
返回值無無支援 (Future.get())
異常處理困難困難自動傳播到 Future.get()
資源管理手動手動線程池復用、關閉可控
適用場景簡單演示、教學輕量任務、共享任務實例生產環境、高併發、需結果/超時

最佳實踐建議

  1. 業務代碼統一使用線程池,避免頻繁創建銷毀線程開銷。
  2. 需返回值/拋出異常選 Callable,無返回值選 Runnable。
  3. 生產環境避免 Executors 默認工廠(FixedThreadPool 無界隊列 OOM 風險),自定義 ThreadPoolExecutor 設置有界隊列、拒絕策略、線程命名。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved