7. Netty源码分析之Future和Promise

Posted lovezmc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7. Netty源码分析之Future和Promise相关的知识,希望对你有一定的参考价值。

一、Future

  Future源自java.util.concurrent.Future,用于获取异步操作的结果,它通过get()方法获取异步操作结果,操作尚未完成,则阻塞。

  Netty认为这是一个很不好的设计,操作结束时间难以确定,何不通过回调的方式获取结果呢。Netty的ChannelFuture通过监听的方式,当操作结束时调用注册在上面的方法获取操作结果。

  Future的方法定义:

public interface Future<V> extends java.util.concurrent.Future<V> 
    //执行是否成功
    boolean isSuccess();

    //是否可以取消
    boolean isCancellable();

    //操作失败时,返回失败原因
    Throwable cause();

    //添加Listener,当操作结束后回调
    Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);

    //移除listener
    Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... listeners);

    //阻塞至任务结束,如果操作失败,抛异常
    Future<V> sync() throws InterruptedException;

    //不响应中断的阻塞
    Future<V> syncUninterruptibly();

    //阻塞等待任务,操作失败不抛异常
    //不要在ChannelHandler中调用ChannelFuture的await()方法,这样会导致死锁
    //原因是发起IO操作后,由IO线程负责异步通知发起IO线程的用户线程,如果IO线程和用户线程是统一线程,就会导致IO线程等待自己通知操作完成,这就导致了死锁
    Future<V> await() throws InterruptedException;
    Future<V> awaitUninterruptibly();
    boolean await(long timeout, TimeUnit unit) throws InterruptedException;
    boolean await(long timeoutMillis) throws InterruptedException;
    boolean awaitUninterruptibly(long timeout, TimeUnit unit);
    boolean awaitUninterruptibly(long timeoutMillis);

    //获取执行结果,不阻塞
    V getNow();

    //取消任务执行
    @Override
    boolean cancel(boolean mayInterruptIfRunning);

二、ChannelFuture

  这个接口只是将Future的方法的返回参数改为ChannelFuture,这样就可以使用一直点下去,有点像builder模式(ex: channelFuture.addListener(..).addListener(..).sync())。

public interface ChannelFuture extends Future<Void> 

    //返回和ChannelFuture关联的Channel
    Channel channel();

    @Override
    ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener);

    @Override
    ChannelFuture addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);

    @Override
    ChannelFuture removeListener(GenericFutureListener<? extends Future<? super Void>> listener);

    @Override
    ChannelFuture removeListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);

    @Override
    ChannelFuture sync() throws InterruptedException;

    @Override
    ChannelFuture syncUninterruptibly();

    @Override
    ChannelFuture await() throws InterruptedException;

    @Override
    ChannelFuture awaitUninterruptibly();

三、Promise

  Promise继承了Future,是可写的Future,因为 future 不支持写操作接口,netty 使用 promise 扩展了 future, 可以对异步操作结果进行设置。

public interface Promise<V> extends Future<V> 

    // 标记该 future 成功及设置其执行结果,并且会通知所有的 listeners
    // 如果操作失败,将抛出异常(失败指的是该 future 已经有了结果了,成功的结果,或者失败的结果)
    Promise<V> setSuccess(V result);

    // 和 setSuccess 方法一样,只不过如果失败,它不抛异常,返回 false
    boolean trySuccess(V result);

    // 标记该 future 失败,及其失败原因。
    // 如果失败,将抛出异常(失败指的是已经有了结果了)
    Promise<V> setFailure(Throwable cause);

    // 标记该 future 失败,及其失败原因。
    // 如果已经有结果,返回 false,不抛出异常
    boolean tryFailure(Throwable cause);

    // 标记该 future 不可以被取消
    boolean setUncancellable();

    // 同ChannelFuture一样,返回this
    @Override
    Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
    @Override
    Promise<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
    @Override
    Promise<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
    @Override
    Promise<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... listeners);

    @Override
    Promise<V> await() throws InterruptedException;
    @Override
    Promise<V> awaitUninterruptibly();
    @Override
    Promise<V> sync() throws InterruptedException;
    @Override
    Promise<V> syncUninterruptibly();

四、ChannelPromise

  ChannelPromise继承了ChannelFuture和Promise,将功能聚合起来。同样的,方法返回值改成ChannelPromise以便调用。

public interface ChannelPromise extends ChannelFuture, Promise<Void> 

    // 覆写 ChannelFuture 中的 channel() 方法,其实这个方法一点没变
    @Override
    Channel channel();

    // 下面几个方法是覆写 Promise 中的接口,为了返回值类型是 ChannelPromise
    @Override
    ChannelPromise setSuccess(Void result);
    ChannelPromise setSuccess();
    boolean trySuccess();
    @Override
    ChannelPromise setFailure(Throwable cause);

    // 到这里大家应该都熟悉了,下面几个方法的覆写也是为了得到 ChannelPromise 类型的实例
    @Override
    ChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener);
    @Override
    ChannelPromise addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);
    @Override
    ChannelPromise removeListener(GenericFutureListener<? extends Future<? super Void>> listener);
    @Override
    ChannelPromise removeListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);

    @Override
    ChannelPromise sync() throws InterruptedException;
    @Override
    ChannelPromise syncUninterruptibly();
    @Override
    ChannelPromise await() throws InterruptedException;
    @Override
    ChannelPromise awaitUninterruptibly();

    /**
     * Returns a new @link ChannelPromise if @link #isVoid() returns @code true otherwise itself.
     */
    // 我们忽略这个方法吧。
    ChannelPromise unvoid();

 

  

以上是关于7. Netty源码分析之Future和Promise的主要内容,如果未能解决你的问题,请参考以下文章

5. Netty源码分析之ChannelPipeline 和 ChannelHanler

Java分布式框架netty之NIO框架区别分析

netty的Future异步回调难理解?手写个带回调异步框架就懂了附源码

[netty4][netty-common]Future与Promise分析

高性能Netty之内存池源码分析

2. Netty源码分析之使用篇