多核處理器普及迫使開發者編寫高擴展性應用以充分利用硬體資源,舊系統亦需移植新架構。提供高擴展性並發構建組件(如 ConcurrentHashMap 替代同步 HashTable)是引入並行的有效途徑。本文介紹 Amino 開源庫建構高擴展性 Java 組件的核心原則。
分析器需提供線程、鎖競爭、同步點詳盡資訊。Amino 專案使用工具:
傳統調優後,檢視共享資料多線程存取模式。若 100 線程競爭單一 HashTable,監視器使用頻繁。解法:採用分段鎖設計的 ConcurrentHashMap,線程針對多個子組件競爭,大幅降低衝突機率。
另一技術:針對堆疊「壓入/彈出」等語義相反操作,避免觸及核心資料結構(Hendler/Shavit/Yerushalmi 提出,Amino 已實作)。圖 1 展示 EBStack 優於 TreiberStack 的效能。

傳統鎖機制易導致死鎖、活鎖、優先權反轉、鎖競爭。無鎖演算法(CAS 基礎)解決多數問題,JDK 1.5+ 內建 ConcurrentLinkedQueue、AtomicInteger 等。Amino 採用最新研究成果,擴展性優於鎖基組件(低核心數下吞吐量略遜,但通常更優)。
JDK ConcurrentLinkedQueue 基於 Michael-Scott 單向鏈表,出隊 1 次 CAS,入隊 2 次 CAS。分析顯示 CAS 佔執行時間 ~46%(圖 2),現代多處理器上 CAS 耗時比載入/儲存長一個數量級(需獨佔並沖刷寫入緩衝)。

Mozes-Shavit 隊列 (MoS-queue) 改用雙向鏈表,指針更新僅需 1 次儲存,亂序時修復。基準測試證實高線程數下 MoS-queue 顯著優於 JDK 實作(圖 3)。

JVM 線程本地分配緩衝 (TLAB) 高效,但高頻分配會快速耗盡。循環中需暫時物件時,改用 ThreadLocal 重用物件優於頻繁分配。圖 4 對比顯示 ThreadLocal 顯著降低分配開銷。

高擴展性組件設計原則:降低熱點競爭、採用無鎖演算法、極小化 CAS、減少記憶體分配。原則有益但無法替代嚴謹測試與調優。