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

Active Object 並發模式在 Java 中的演進與最佳實踐:從 C++ 核心原理到 Executor Framework

     編輯:Java 相關知識

核心概念:並發對象與 Active Object 模式

並發對象:方法調用與執行分離於不同線程的對象,即方法異步執行。這是面向對象概念在多線程環境下的自然延伸。

Active Object 模式本質:解耦方法調用與執行。調用發生在客戶端線程,執行發生在專屬的 Active Object 線程。對調用者透明,如同調用普通對象方法。

C++ 經典實現:六大角色協作

角色職責

  • Proxy(代理):運行在調用者線程,定義公共接口,將調用封裝為 Method Request 放入 Activation List,返回 Future。
  • Method Request(方法請求):封裝調用上下文(參數、目標 Servant、結果 Future),含 canRun()(同步守衛條件)與 call()(綁定執行邏輯)。
  • Activation List(激活隊列):線程安全的 Method Request 隊列,生產者(調用者)入隊,消費者(Scheduler)出隊。基於生產者/消費者模型。
  • Scheduler(調度器):運行在 Active Object 線程,輪詢 Activation List,根據策略(FIFO、優先級等)選擇可運行請求,調用 call() 執行。
  • Servant(服務者):實現業務邏輯的核心類,純粹領域邏輯,無線程同步代碼,利於復用。
  • Future(期物):異步結果佔位符,提供同步等待、超時等待、異步輪詢三種獲取結果方式。

執行流程(時序圖解析)

  1. 調用者調用 Proxy.get() → Proxy 創建 Get Request → Scheduler insert() 入隊 → 返回 Message_Future(步驟 1-6,調用者線程)。
  2. Scheduler 線程循環:從 Activation List 取請求 → canRun() 判斷守衛條件(如隊列非空) → 滿足則 remove() 出隊 → call() 執行 Servant.get() → 結果存入 Future → 刪除 Request(步驟 7-12,Active Object 線程)。
  3. 調用者通過 future.result() 同步/超時/異步獲取結果。

關鍵代碼片段

// Proxy 入口
void put(Message msg) { scheduler.insert(new Put(servant, msg)); }
Message_Future get() { 
    Message_Future f; 
    scheduler.insert(new Get(&servant, f)); 
    return f; 
}

// Method Request 守衛條件
class Get extends Method_Request {
    bool can_run() const { return !servant->empty(); } // 隊列非空才能取
    void call() { result = servant->get(); }
}

// Scheduler 調度循環
void dispatch() {
    for (;;) {
        for (request = act_list.begin(); request != act_list.end(); ++request) {
            if ((*request).can_run()) {
                act_list.remove(*request);
                (*request).call();
                delete *request;
            }
        }
    }
}

Java 中的 Active Object:Executor Framework

Timer/TimerTask 的局限

JDK 1.3 引入,單線程執行導致任務調度不精確,長任務阻塞後續任務。Java 5+ 推薦使用 ScheduledThreadPoolExecutor 替代。

Executor Framework:簡化的 Active Object

Java 5 java.util.concurrent.Executor 框架是 Active Object 模式的標準化實現,但極大簡化了角色分工:

  • Task (Runnable/Callable):融合了 Method Request + Servant,run()/call() 直接包含業務邏輯。
  • Executor:相當於 Scheduler + Activation List,管理線程池、任務隊列、調度策略。
  • Future:保留標準 Future 接口,支持結果獲取、取消、狀態查詢。
  • 無顯式 Proxy:直接 executor.execute(task) 或 submit(task),並發細節暴露給調用者。

代碼對比

// Active Object 風格(隱藏並發細節)
MQ_Proxy queue;
Message_Future f = queue.get();
Message msg = f.result(); // 像調用普通方法

// Executor 風格(顯式提交任務)
Executor exec = Executors.newFixedThreadPool(100);
Future<Message> f = exec.submit(() -> {
    return handleRequest(connection); // 業務邏輯在 Task 內
});
Message msg = f.get();

選型指南:何時用哪種?

維度Active Object 完整模式Executor Framework
並發細節封裝完全隱藏,調用如同普通對象暴露任務提交模型,調用者感知並發
靈活性/控制力高(自定義調度策略、守衛條件、優先級)中(依賴 ThreadPoolExecutor 策略配置)
開發複雜度高(需實現六大角色、同步機制)低(標準 API,開箱即用)
適用場景領域模型驅動、需透明並發、複雜同步約束任務並行處理、服務端請求分發、批量異步作業

優缺點總結

優勢

  • 顯著提升並發性與響應度(調用者線程與執行線程並行)。
  • 封裝線程同步複雜度,調用者無需關心鎖、條件變量。
  • 執行順序可與調用順序解耦,支持優先級、截止時間等優化策略(QoS 提升)。

劣勢

  • 額外性能開銷:線程上下文切換、同步開銷、內存拷貝。
  • 調試困難:異步調用堆棧斷裂,涉及線程調度、同步時序問題難以復現。

結語

Active Object 是並發編程的經典模式,Java Executor Framework 將其工業化、標準化。理解底層 C++ 實現機制(Proxy、Activation List、Scheduler、Servant、Future、Method Request),有助於在 Java 中正確選擇:需領域透明並發時自建 Active Object;需高吞吐任務處理時直接用 Executor。兩者同源異流,核心皆是「調用與執行分離」。

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