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

構建 Java 並發模型框架:Active Object 模式實現異步服務與邏輯解耦

     編輯:Java 相關知識

痛點:同步調用耦合業務與併發邏輯

直接在 Service 方法加 synchronized 存在四大問題:

  1. 單/多線程版本雙維護
  2. Client 同步阻塞,服務品質下降
  3. 無法實現優先級佇列、熔斷、限流等進階控制
  4. 業務邏輯與併發控制糾纏,難以復用測試

核心模式:Active Object(主動物件)

類型被動物件主動物件
方法調用同步、阻塞異步、非阻塞
執行執行緒呼叫者執行緒自身專屬執行緒
回傳值處理直接回傳Future/Callback/Event
適用場景簡單、低併發高併發、需排隊控制

框架三大核心組件

1. MethodRequest —— 命令模式封裝請求

public interface MethodRequest {
    void call(); // 執行入口
}

// 具體命令:封裝 sayHello 請求
class SayHelloRequest implements MethodRequest {
    private final Service service;
    
    public SayHelloRequest(Service service) {
        this.service = service;
    }
    
    @Override
    public void call() {
        service.sayHello(); // 在 Active Object 執行緒中執行
    }
}

2. ActiveQueue —— 生產者消費者佇列

public class ActiveQueue {
    private final Queue queue = new LinkedList<>();
    private final int maxSize;
    
    public ActiveQueue(int maxSize) {
        this.maxSize = maxSize;
    }
    
    // 生產者:Client 提交請求
    public synchronized void enqueue(MethodRequest request) throws InterruptedException {
        while (queue.size() >= maxSize) {
            wait(); // 佇列滿,等待消費
        }
        queue.add(request);
        notifyAll(); // 喚醒消費者
    }
    
    // 消費者:Active Object 取走執行
    public synchronized MethodRequest dequeue() throws InterruptedException {
        while (queue.isEmpty()) {
            wait(); // 佇列空,等待生產
        }
        MethodRequest request = queue.remove();
        notifyAll(); // 喚醒生產者
        return request;
    }
}

3. ActiveObject —— 專屬執行緒循環消費

public class ActiveObject extends Thread {
    private final ActiveQueue queue;
    private volatile boolean running = true;
    
    public ActiveObject(ActiveQueue queue) {
        this.queue = queue;
        setDaemon(true); // 不阻塞 JVM 關閉
        setName("ActiveObject-Worker");
        start();
    }
    
    public void enqueue(MethodRequest request) throws InterruptedException {
        queue.enqueue(request);
    }
    
    @Override
    public void run() {
        while (running) {
            try {
                MethodRequest request = queue.dequeue();
                request.call(); // 核心:在專屬執行緒執行業務邏輯
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break; // 優雅退出
            } catch (Exception e) {
                // 記錄錯誤,防止單一任務異常導致 Worker 死亡
                System.err.println("任務執行異常: " + e.getMessage());
            }
        }
    }
    
    public void shutdown() {
        running = false;
        interrupt();
    }
}

服務代理:對 Client 透明化異步

public class ServiceProxy implements Service {
    private final Service realService = new ServiceImpl();
    private final ActiveObject activeObject;
    
    public ServiceProxy() {
        this.activeObject = new ActiveObject(new ActiveQueue(100));
    }
    
    @Override
    public void sayHello() {
        try {
            activeObject.enqueue(new SayHelloRequest(realService));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("提交任務被中斷", e);
        }
    }
}

Client 使用零感知

// 引入並發邏輯前
Service s = new ServiceImpl();
Client c = new Client(s);
c.requestService(); // 同步阻塞

// 引入並發邏輯後
Service s = new ServiceProxy(); // 僅此行變更
Client c = new Client(s);
c.requestService(); // 瞬間返回,異步執行

框架擴展點

需求擴展方案
支援回傳值MethodRequest 回傳 Future,ActiveQueue 存 FutureTask
優先級佇列ActiveQueue 改用 PriorityBlockingQueue,MethodRequest 實現 Comparable
定時/週期任務加入 ScheduledExecutorService,支援 scheduleAtFixedRate
叢集高可用引入分散式鎖、領導者選舉、狀態同步
監控指標佇列長度、處理延遲、拒絕次數、執行緒池狀態

優缺點總結

優點缺點
業務邏輯與併發模型完全解耦增加類數量與間接層次
Client 非阻塞,回應極快大量 ActiveObject 導致執行緒切換開銷
靈活的佇列控制(優先級、限流、熔斷)異步除錯困難(堆疊追蹤斷裂)
ServiceImpl 可獨立單元測試無回傳值場景受限(需 Future 擴展)
符合單一職責、開閉原則簡單場景過度設計

現代替代:CompletableFuture + 執行緒池

// 輕量級異步服務
@Service
public class AsyncService {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
    
    public CompletableFuture sayHelloAsync() {
        return CompletableFuture.runAsync(() -> {
            // 業務邏輯
            System.out.println("Hello World!");
        }, executor);
    }
}

// Client
asyncService.sayHelloAsync()
    .thenRun(() -> System.out.println("完成"))
    .exceptionally(ex -> { log.error(ex); return null; });

總結

Active Object 框架展示了併發模式組件化的經典思路:命令封裝請求 + 佇列解耦生產消費 + 專屬執行緒隔離執行。雖現代開發多用 CompletableFuture、ExecutorService、Disruptor、Reactor 等成熟框架,但理解 Active Object 內部機制,有助於設計高內聚、低耦合的併發系統架構。

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