Java 5 引入 java.util.concurrent 包,徹底改變了多線程開發面貌。本文通過構建網絡服務器模型,實戰演練線程池、阻塞隊列、可重入鎖、Callable/Future、泛型等核心特性。
痛點:短連接高併發下,線程創建/銷毀開銷巨大,甚至導致 OOM。
ExecutorService pool = Executors.newFixedThreadPool(10); // 固定 10 線程
ServerSocket serverSocket = new ServerSocket(19527);
serverSocket.setReuseAddress(true);
while (true) {
Socket socket = serverSocket.accept(); // 阻塞等待連接
pool.execute(new ServiceThread(socket)); // 提交 Runnable 任務
}
class ServiceThread implements Runnable {
private static final ReentrantLock lock = new ReentrantLock();
private static int count = 0;
private final Socket socket;
public ServiceThread(Socket socket) { this.socket = socket; }
private int getCount() {
lock.lock();
try { return count; }
finally { lock.unlock(); }
}
private void increaseCount() {
lock.lock();
try { count++; }
finally { lock.unlock(); }
}
public void run() {
try {
increaseCount();
int id = getCount();
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.write(("hello, id = " + id + "\r\n").getBytes());
// 費時任務異步執行:Callable + Future
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(new TimeConsumingTask());
dos.write("let's do something other\r\n".getBytes());
String result = future.get(); // 阻塞獲取結果,若已完成則立即返回
dos.write((result + "\r\n").getBytes());
} catch (Exception e) { e.printStackTrace(); }
}
}
class TimeConsumingTask implements Callable { // 泛型指定返回類型
public String call() throws Exception {
System.out.println("Time-consuming task running...");
Thread.sleep(3000); // 模擬耗時操作
return "ok, result produced after long time";
}
}
| 特性 | 傳統寫法 | Java 5 寫法 | 優勢 |
|---|---|---|---|
| 線程管理 | new Thread() | ExecutorService + 線程池 | 復用線程、控制併發數、拒絕策略 |
| 同步鎖 | synchronized | ReentrantLock | 可中斷、超時獲取、公平鎖、條件變量 |
| 異步結果 | 共享變量 + wait/notify | Callable + Future | 類型安全、異常傳播、可取消、超時獲取 |
| 類型安全 | Object 強轉 | 泛型 | 編譯期檢查、消除強轉 |
Future future = executor.submit(task);
// 此處主線程可繼續做其他事...
dos.write("other work".getBytes()); // 並行執行!
String result = future.get(); // 此處阻塞直到任務完成
// 若任務已完成:立即返回結果
// 若任務未完成:等待完成
// 若任務拋異常:拋出 ExecutionException
這實現了「提交即忘、需要時取」的異步編程模式,充分利用多核 CPU。
ThreadPoolExecutor 精確控制核心/最大線程數、隊列類型、拒絕策略CompletionService 批量管理 Future 結果