java.util.concurrent 不僅提供線程安全集合,更包含強大的同步實用程式,解決「調節/限制線程執行」的進階需求。本文介紹五大核心同步結構。
控制同時訪問特定資源的線程數。構造時指定許可證總數,acquire() 獲取(阻塞直到可用),release() 歸還。典型場景:限流、資源池訪問控制。
Semaphore sem = new Semaphore(3); // 僅允許 3 線程並發
sem.acquire();
try { /* 高併發敏感操作 */ } finally { sem.release(); }
測試顯示:10 個線程啟動,僅 3 個同時進入臨界區,其餘阻塞等待。
一個計數器,線程調用 await() 阻塞,其他線程調用 countDown() 遞減。計數歸零時,所有等待線程同時釋放。雙重用法:
await(),主線程 countDown() 一次性放行所有線程。countDown(),主線程 await() 等待全部完成。賽馬模擬完美演示:閘門開啟 → 馬兒奔跑 → 衝線統計名次。
直接 new Thread() 存在平台差異(重量級/輕量級)與生命週期管理難題。Executor 介面統一提交任務:exec.execute(runnable)。ExecutorService 進一步提供:
Future(非阻塞獲取結果、取消任務)。invokeAll/invokeAny。shutdown()/shutdownNow()。注意: JVM 無內建線程池,需自行創建或依賴容器提供。
擴展 ExecutorService,支援定時/周期性執行。scheduleAtFixedRate(task, initialDelay, period, TimeUnit) 輕鬆實現心跳檢測:
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
ses.scheduleAtFixedRate(() -> System.out.println("PING!"), 5, 5, TimeUnit.SECONDS);
// 取消:scheduledFuture.cancel(true);
無需手動管理線程狀態、前後台標記,取消機制內建於返回的 ScheduledFuture。
幾乎所有阻塞方法(lock.tryLock(timeout)、queue.poll(timeout)、latch.await(timeout))均支援 timeout + TimeUnit 參數。強制開發者處理超時邏輯(重試、降級、報警),從根源上減少死鎖與系統掛起,生產環境必備。
掌握 Semaphore(限流)、CountDownLatch(協同閘門)、ExecutorService(任務執行服務)、ScheduledExecutorService(定時調度)、超時參數(容錯基石)五大工具,配合第一部分的併發集合,構建健壯多線程系統的核心工具箱已備齊。下一主題:JAR 包管理 5 大祕密。