Allen Holub 指出 Java 線程模型是語言最薄弱環節:非面向對象、語法支援極少、僅適用微型應用。現有類庫(如 Concurrent 套件)屬「創可貼」式修補,長遠看需從語言語法層面解決。本文整理其核心改進提案。
OO 設計思考的是「同步/異步訊息」,而非「線程」。Java Thread 本質是 run() 程序,缺乏物件、訊息、主動物件等概念。Swing/AWT 事件隊列實際是單一主動物件,但未語言化。
$task FileIoTask {
$error { $ex.printStackTrace(); } // 異常處理子句
$asynchronous void readFile(String path) { /* 背景執行 */ }
$asynchronous void writeFile(String path, byte[] data) { /* 背景執行 */ }
String getStatus() { /* 同步執行 */ } // 非異步方法同步運行
}
$asynchronous 方法自動排入內建隊列,由背景線程序列化執行,消除大多數同步問題$pooled(n) 修飾符啟用線程池,$pool_size 偽欄位查詢池大小synchronized(x && y && z) { ... } // 原子獲取多把鎖,避免死鎖
synchronized(x || y || z) { ... } // 獲取任一鎖
synchronized(...)[1000] { ... } // 1秒超時
synchronized[1000] void f() { ... } // 方法級超時
TimeoutException (RuntimeException 子類)interrupt() 等待鎖的線程拋出 SynchronizationExceptionwait() 回傳 boolean:true=正常喚醒,false=超時await(condition) 自動阻塞至條件滿足wait() 按逆序釋放所有鎖,喚醒後按原序重獲(極難正確實現,徵求社群方案)Thread 永遠搶佔式(對應 Solaris LWP)Runnable 映射協作式綠色線程,多個 Runnable 綁定單一 Thread(LWP)new Thread(r1, r2, r3) 建構子支援多綠色線程共享一 LWP$send(Object o) / $send(Object o, long timeout)
$receive() / $receive(long timeout)
// 內部阻塞隊列自動建立
wait_for_start():阻塞至線程 run() 真正啟動$reading { ... } // 多線程並發讀
$writing { ... } // 單線程獨佔寫
// 讀寫互斥、寫寫互斥、可配置寫優先權
start() 生效(延遲啟動)synchronized Foo() { ... }package 關鍵字顯式聲明包可見性private protected(僅子類可見,不含包)private private:僅 this 可見,連同類其他實例不可見public(Fred) void m():僅授權 Fred 類別調用(優於 C++ friend)private,提供 $property 供 Bean 工具反射存取$immutable 修飾符:所有欄位 final、引用指向不可變物件final 欄位誤報未初始化的編譯器 Bug(存在三年未修)synchronized 區塊執行完畢,確保資源釋放stop() 改為「延遲停止」:釋放所有鎖後拋出不可捕獲異常終止 run()suspend() 持有鎖時拋出運行時異常,或延遲至釋放鎖後掛起InputStream、Socket、檔案) 支援 interrupt() 中斷與超時參數join() 等待群組內所有線程終止Java 語言偉大但線程模型設計不足。上述提案若能納入語言標準(或等效替代),將從根本解決併發編程痛苦。Java 正在演進,仍有改進空間。