Java 創建線程有三種主流方式,本文對比優缺點,並給出生產環境推薦的「線程池 + Callable」完整範例。
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();
}
}
缺點:單繼承限制,線程對象與任務耦合,無返回值,難以管理生命週期。
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();
}
}
優點:任務與線程分離,支援多線程共享同一任務實例,避開單繼承。缺點:仍無返回值,手動管理線程啟動/停止。
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 | 實現 Runnable | ExecutorService+Callable |
|---|---|---|---|
| 返回值 | 無 | 無 | 支援 (Future.get()) |
| 異常處理 | 困難 | 困難 | 自動傳播到 Future.get() |
| 資源管理 | 手動 | 手動 | 線程池復用、關閉可控 |
| 適用場景 | 簡單演示、教學 | 輕量任務、共享任務實例 | 生產環境、高併發、需結果/超時 |
Callable,無返回值選 Runnable。Executors 默認工廠(FixedThreadPool 無界隊列 OOM 風險),自定義 ThreadPoolExecutor 設置有界隊列、拒絕策略、線程命名。