Promise 源码分析

在 Netty 中,Promise 接口继承自 Future,用于表示可以设置结果的异步操作。Promise 提供了一些额外的方法,用于设置操作的成功或失败状态。通过 Promise,用户可以主动地控制异步操作的结果状态,而不仅仅是被动地等待结果。

Promise 接口

Promise 接口继承自 Future,并增加了一些用于设置结果的方法。

Promise 接口定义
public interface Promise<V> extends Future<V> {
    Promise<V> setSuccess(V result);
    boolean trySuccess(V result);
    Promise<V> setFailure(Throwable cause);
    boolean tryFailure(Throwable cause);
    boolean setUncancellable();
}

DefaultPromise

DefaultPromisePromise 接口的一个实现类,提供了实际的状态管理和结果设置功能。

DefaultPromise 类的核心代码

以下是 DefaultPromise 类的部分核心代码,用于解释其工作原理。

public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
    private static final long serialVersionUID = -7696902375083286369L;

    // 保存结果
    private volatile Object result;
    
    // 监听器集合
    private Object listeners;
    
    // 是否正在通知监听器
    private boolean notifyingListeners;

    @Override
    public Promise<V> setSuccess(V result) {
        if (setSuccess0(result)) {
            notifyListeners();
            return this;
        }
        throw new IllegalStateException("complete already: " + this);
    }

    @Override
    public boolean trySuccess(V result) {
        if (setSuccess0(result)) {
            notifyListeners();
            return true;
        }
        return false;
    }

    @Override
    public Promise<V> setFailure(Throwable cause) {
        if (setFailure0(cause)) {
            notifyListeners();
            return this;
        }
        throw new IllegalStateException("complete already: " + this, cause);
    }

    @Override
    public boolean tryFailure(Throwable cause) {
        if (setFailure0(cause)) {
            notifyListeners();
            return true;
        }
        return false;
    }

    private boolean setSuccess0(V result) {
        if (this.result != null) {
            return false;
        }
        this.result = result == null ? SUCCESS : result;
        return true;
    }

    private boolean setFailure0(Throwable cause) {
        if (this.result != null) {
            return false;
        }
        this.result = cause;
        return true;
    }

    private void notifyListeners() {
        if (notifyingListeners || listeners == null) {
            return;
        }
        notifyingListeners = true;
        for (;;) {
            final Object listeners = this.listeners;
            this.listeners = null;
            if (listeners instanceof GenericFutureListener) {
                @SuppressWarnings("unchecked")
                final GenericFutureListener<Future<? super V>> l = (GenericFutureListener<Future<? super V>>) listeners;
                l.operationComplete(this);
            } else {
                @SuppressWarnings("unchecked")
                final GenericFutureListener<Future<? super V>>[] array = (GenericFutureListener<Future<? super V>>[]) listeners;
                for (GenericFutureListener<Future<? super V>> l : array) {
                    if (l == null) {
                        break;
                    }
                    l.operationComplete(this);
                }
            }
            if (this.listeners == null) {
                break;
            }
        }
        notifyingListeners = false;
    }

    @Override
    public Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener) {
        if (listener == null) {
            throw new NullPointerException("listener");
        }
        if (isDone()) {
            notifyListener(this, listener);
            return this;
        }
        synchronized (this) {
            if (!isDone()) {
                if (listeners == null) {
                    listeners = listener;
                } else if (listeners instanceof GenericFutureListener) {
                    listeners = new GenericFutureListener[]{(GenericFutureListener<?>) listeners, listener};
                } else {
                    GenericFutureListener<?>[] array = (GenericFutureListener<?>[]) listeners;
                    int size = array.length;
                    GenericFutureListener<?>[] newArray = new GenericFutureListener[size + 1];
                    System.arraycopy(array, 0, newArray, 0, size);
                    newArray[size] = listener;
                    listeners = newArray;
                }
                return this;
            }
        }
        notifyListener(this, listener);
        return this;
    }

    private static void notifyListener(Future<?> future, GenericFutureListener<?> l) {
        try {
            l.operationComplete(future);
        } catch (Throwable t) {
            if (logger.isWarnEnabled()) {
                logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationComplete()", t);
            }
        }
    }
}

DefaultPromise 核心逻辑

  1. 结果管理:

    • result 保存操作的结果,可以是成功的结果或失败的异常。
  2. 回调机制:

    • listeners 保存添加的回调监听器。
    • notifyingListeners 表示是否正在通知监听器。
  3. 状态设置方法:

    • setSuccess(V result)trySuccess(V result) 设置操作成功。
    • setFailure(Throwable cause)tryFailure(Throwable cause) 设置操作失败。
  4. 监听器通知:

    • notifyListeners() 方法遍历并调用所有已添加的监听器。
  5. 添加监听器:

    • addListener(GenericFutureListener<? extends Future<? super V>> listener) 方法用于添加监听器,并在操作完成时立即通知。

使用示例

以下是一个使用 DefaultPromise 的示例代码:

import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.ImmediateEventExecutor;

public class PromiseExample {
    public static void main(String[] args) throws InterruptedException {
        EventExecutor executor = ImmediateEventExecutor.INSTANCE;
        DefaultPromise<String> promise = new DefaultPromise<>(executor);

        promise.addListener(new GenericFutureListener<Future<? super String>>() {
            @Override
            public void operationComplete(Future<? super String> future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("Operation completed successfully: " + future.get());
                } else {
                    System.err.println("Operation failed: " + future.cause());
                }
            }
        });

        // 模拟异步操作
        executor.execute(() -> {
            try {
                Thread.sleep(1000);
                promise.setSuccess("Hello, Netty!");
            } catch (InterruptedException e) {
                promise.setFailure(e);
            }
        });

        // 等待操作完成
        promise.await();
    }
}

总结

在 Netty 中,Promise 接口继承自 Future,并提供了额外的方法用于设置异步操作的结果。DefaultPromisePromise 接口的一个实现类,提供了实际的状态管理和回调通知机制。通过 Promise,用户可以主动地控制异步操作的结果状态,并通过回调机制在操作完成后执行特定的逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值