首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 線程模型根本缺陷與語言級改進提案

     編輯:Java 相關知識

Allen Holub 指出 Java 線程模型是語言最薄弱環節:非面向對象、語法支援極少、僅適用微型應用。現有類庫(如 Concurrent 套件)屬「創可貼」式修補,長遠看需從語言語法層面解決。本文整理其核心改進提案。

核心問題:缺乏「任務」抽象

OO 設計思考的是「同步/異步訊息」,而非「線程」。Java Thread 本質是 run() 程序,缺乏物件、訊息、主動物件等概念。Swing/AWT 事件隊列實際是單一主動物件,但未語言化。

提案一:引入 $task 關鍵字(主動物件語言化)

$task FileIoTask {
    $error { $ex.printStackTrace(); } // 異常處理子句
    
    $asynchronous void readFile(String path) { /* 背景執行 */ }
    $asynchronous void writeFile(String path, byte[] data) { /* 背景執行 */ }
    
    String getStatus() { /* 同步執行 */ } // 非異步方法同步運行
}
  • $asynchronous 方法自動排入內建隊列,由背景線程序列化執行,消除大多數同步問題
  • $pooled(n) 修飾符啟用線程池,$pool_size 偽欄位查詢池大小
  • 參數必須不可變,運行時語義保證
  • 支援繼承介面、繼承類別、繼承其他 $task

提案二:擴展 synchronized 語法

synchronized(x && y && z) { ... }  // 原子獲取多把鎖,避免死鎖
synchronized(x || y || z) { ... }  // 獲取任一鎖
synchronized(...)[1000] { ... }    // 1秒超時
synchronized[1000] void f() { ... } // 方法級超時
  • 拋出 TimeoutException (RuntimeException 子類)
  • interrupt() 等待鎖的線程拋出 SynchronizationException
  • 編譯器自動重排鎖獲取順序消除經典死鎖
  • 等待時周期性釋放已持有鎖打破潛在死鎖

提案三:改進 wait()/notify()

  • wait() 回傳 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() { ... }

提案八:volatile 語義落地

  • JLS 要求保留 volatile 訪問順序,多數 JVM 忽略,多處理器下嚴重破壞可見性
  • Bill Pugh (馬里蘭大學) 正推動 JSR-133 修復

提案九:存取控制精細化

  • 強制 package 關鍵字顯式聲明包可見性
  • 恢復 private protected(僅子類可見,不含包)
  • 新增 private private:僅 this 可見,連同類其他實例不可見
  • public(Fred) void m():僅授權 Fred 類別調用(優於 C++ friend)
  • 非不可變欄位強制 private,提供 $property 供 Bean 工具反射存取

提案十:真正不可變類型

  • $immutable 修飾符:所有欄位 final、引用指向不可變物件
  • 修復內部類導致 final 欄位誤報未初始化的編譯器 Bug(存在三年未修)

提案十一:靜態欄位存取保護

  • 實例方法存取非不可變靜態欄位需顯式同步或編譯器自動加讀寫鎖

提案十二:守護線程優雅關閉

  • JVM 關閉前等待所有 synchronized 區塊執行完畢,確保資源釋放

提案十三:恢復 stop()/suspend()/resume()

  • stop() 改為「延遲停止」:釋放所有鎖後拋出不可捕獲異常終止 run()
  • suspend() 持有鎖時拋出運行時異常,或延遲至釋放鎖後掛起

提案十四:可中斷阻塞 I/O

  • 所有阻塞 I/O (InputStream、Socket、檔案) 支援 interrupt() 中斷與超時參數

提案十五:ThreadGroup 功能補全

  • 實現 join() 等待群組內所有線程終止

結語

Java 語言偉大但線程模型設計不足。上述提案若能納入語言標準(或等效替代),將從根本解決併發編程痛苦。Java 正在演進,仍有改進空間。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved