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

Java 異步 Future 機制深度解析:從 JDK Future 到可監聽 IFuture 實現

     編輯:Java 相關知識

痛點:JDK Future 為什麼不好用?

Future future = executor.submit(task);
future.get();  // 阻塞等待,無法感知完成時刻
// 或輪詢
while (!future.isDone()) { Thread.sleep(100); }  // 低效、延遲

缺陷:無回調通知機制,只能主動輪詢或阻塞等待。

設計目標:IFuture 接口

核心能力:

  • 監聽器模式:`addListener(IFutureListener)` 完成時自動回調
  • 多種等待方式:阻塞/超時/可中斷/不可中斷
  • 豐富狀態查詢:`isSuccess()`、`cause()`、`getNow()`(非阻塞獲取)
  • 線程安全:內部用 `wait/notifyAll` + `volatile` 狀態

IFuture 接口定義

public interface IFuture extends Future {
    boolean isSuccess();           // 是否成功完成
    V getNow();                    // 立即獲取結果(未完成返回 null)
    Throwable cause();             // 失敗原因
    boolean isCancellable();       // 是否可取消

    // 等待完成
    IFuture await() throws InterruptedException;
    boolean await(long timeout, TimeUnit unit) throws InterruptedException;
    IFuture awaitUninterruptibly();
    boolean awaitUninterruptibly(long timeout, TimeUnit unit);

    // 監聽器
    IFuture addListener(IFutureListener listener);
    IFuture removeListener(IFutureListener listener);
}

public interface IFutureListener {
    void operationCompleted(IFuture future) throws Exception;
}

核心實現:AbstractFuture

狀態管理

// 三種終態對象
private static final Object SUCCESS_SIGNAL = new Object();  // 正常完成,結果為 null
private static final class CauseHolder { final Throwable cause; ... }  // 異常完成
// 正常完成有結果:直接存結果對象

volatile Object result;  // null=未完成,非空=已完成
CopyOnWriteArrayList> listeners = new CopyOnWriteArrayList<>();

完成觸發:notifyAll + 監聽器回調

protected boolean setSuccess0(Object result) {
    synchronized (this) {
        if (this.result != null) return false;  // 已完成
        this.result = (result == null) ? SUCCESS_SIGNAL : result;
        notifyAll();  // 喚醒所有 await 線程
    }
    notifyListeners();  // 異步回調監聽器
    return true;
}

protected boolean setFailure0(Throwable cause) {
    synchronized (this) {
        if (this.result != null) return false;
        this.result = new CauseHolder(cause);
        notifyAll();
    }
    notifyListeners();
    return true;
}

private void notifyListeners() {
    for (IFutureListener l : listeners) {
        try { l.operationCompleted(this); } catch (Exception e) { e.printStackTrace(); }
    }
}

等待實現:wait/notifyAll 經典模式

public IFuture await() throws InterruptedException {
    if (isDone()) return this;
    synchronized (this) {
        while (!isDone()) {
            wait();  // 釋放鎖,進入 WAITING
        }
    }
    return this;
}

public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
    long nanos = unit.toNanos(timeout);
    long deadline = System.nanoTime() + nanos;
    synchronized (this) {
        while (!isDone()) {
            if (nanos <= 0) return false;
            wait(nanos / 1_000_000, (int)(nanos % 1_000_000));
            nanos = deadline - System.nanoTime();
        }
        return true;
    }
}

實戰應用:延遲加法任務

public class DelayAdder {
    public IFuture add(long delayMs, int a, int b) {
        DelayAdditionFuture future = new DelayAdditionFuture();
        new Thread(new DelayTask(delayMs, a, b, future)).start();
        return future;
    }

    private static class DelayTask implements Runnable {
        private final long delay; private final int a, b; private final DelayAdditionFuture future;
        public void run() {
            try {
                Thread.sleep(delay);
                future.setSuccess(a + b);  // 正常完成
            } catch (InterruptedException e) {
                future.setFailure(e);      // 異常完成
            }
        }
    }
}

// 客戶端調用:註冊監聽器,無需輪詢
adder.add(3000, 1, 2).addListener(future -> {
    System.out.println("結果: " + future.getNow());  // 3秒後自動打印 3
});

對比總結

| 特性 | JDK Future | IFuture (本文) | Netty Future | CompletableFuture (JDK8) | |------|------------|----------------|--------------|---------------------------| | 回調通知 | ❌ | ✅ | ✅ | ✅ (thenApply 等) | | 同步阻塞 | get() | await() | await() | get()/join() | | 異常處理 | ExecutionException | cause()/get() | cause() | exceptionally() | | 組合操作 | ❌ | 手動實現 | ❌ | thenCompose/allOf 等 | | 適用場景 | 簡單異步 | 需監聽器的舊版本項目 | Netty 生態 | **現代首選** |

建議

  • JDK 8+ 項目:直接使用 CompletableFuture,功能更強、API 更豐富
  • 舊版本/Netty 項目:本文 IFuture 設計可直接落地,理解 `wait/notifyAll` 核心模式
  • 核心心法:狀態機(未完成/成功/失敗/取消)+ 監聽器列表 + 鎖同步 + 狀態變更時 `notifyAll` + 回調
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved