netty学习3:DefaultPromise源码分析

本文通过分析DefaultPromise的源码,探讨了Netty中Promise的实现原理,包括sync方法的阻塞特性、addListener方法用于添加监听器、setSuccess方法设置异步结果并唤醒等待线程以及如何触发监听器回调。Netty的Promise机制为异步编程提供了强大的支持,允许开发者在任务完成时执行回调操作。
摘要由CSDN通过智能技术生成

我们查看DefaultPromise的继承关系图:

 

发现最终实现了Future接口,其实也就是实现异步获取返回值的方法。

先写一个程序 大概了解其功能

public class TestPromise {

    public static void main(String[] args) throws Exception{
        NioEventLoopGroup loopGroup = new NioEventLoopGroup();
        EventLoop next = loopGroup.next();
        Promise<String> promise = new DefaultPromise<>(next);
        promise.addListener(future -> {
            Object s = future.get();
            System.out.println(new Date()+"listner1---promise的future返回值:"+s);
        });
        promise.addListener(new GenericFutureListener<Future<? super String>>() {
            @Override
            public void operationComplete(Future<? super String> future) throws Exception {
                Object s = future.get();
                System.out.println(new Date()+"listner2---promise的future返回值:"+s);
            }
        });
        next.execute(()->{//异步执行run方法
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(new Date() +"execute异步执行");
            promise.setSuccess("promise set ");//设置返回结果 并且通知所有Listeners执行回调方法operationComplete方法
        });
        System.out.println(new Date()+"--------主线程的打印");
        System.out.println(new Date()+"--------主线程阻塞");
        new Thread(()->{
            System.out.println(new Date()+"--------多线程的打印");
            System.out.println(new Date()+"--------多线程阻塞");
            try {
                promise.sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(new Date()+"--------多线程继续运行");
        }).start();
        promise.sync();
        System.out.println(new Date()+"--------主线程继续运行");
    }
}

查看打印结果:

结论如下:

1.sync方法会阻塞当前线程;

2.addListener 会向Promise中添加监听器的对象

2.io.netty.util.concurrent.Promise#setSuccess 可以设置异步执行的返回值到promise对象中

3.setSuccess方法会通知所有监听器,触发回调方法 并且将所有通过sync方法阻塞的线程都唤醒

查看源码

io.netty.util.concurrent.DefaultPromise
public Promise<V> sync() throws InterruptedException {//阻塞线程
        await();//wait阻塞
        rethrowIfFailed();
        return this;
    }

public Promise<V> await() throws InterruptedException {
        if (isDone()) {//如果有返回结果了  直接返回
            return this;
        }

        if (Thread.interrupted()) {//线程被打断
            throw new InterruptedException(toString());
        }

        checkDeadLock();//检查死锁

        synchronized (this) {
            while (!isDone()) {//自旋阻塞  如果返回并设置结果了 就跳出循环
                incWaiters();
                try {
                    wait();
                } finally {
                    decWaiters();
                }
            }
        }
        return this;
    }

public Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener) {//添加监听器对象
        checkNotNull(listener, "listener");

        synchronized (this) {
            addListener0(listener);//添加监听器
        }

        if (isDone()) {//如果线程处理完成有返回结果了
            notifyListeners();//通知监听器
        }

        return this;
    }

private void addListener0(GenericFutureListener<? extends Future<? super V>> listener) {//添加监听器
        if (listeners == null) {
            listeners = listener;
        } else if (listeners instanceof DefaultFutureListeners) {//类型是DefaultFutureListeners对象
            ((DefaultFutureListeners) listeners).add(listener);//其实就是一个监听器的数组对象 add就往数组添加监听器
        } else {
            listeners = new DefaultFutureListeners((GenericFutureListener<?>) listeners, listener);//没有则创建
        }
    }


public Promise<V> setSuccess(V result) {//设置成功的结果对象
        if (setSuccess0(result)) {//设置成功结果对象
            return this;//返回promise对象 能成功拿到结果集
        }
        throw new IllegalStateException("complete already: " + this);
    }


private boolean setSuccess0(V result) {//设置成功的结果对象
        return setValue0(result == null ? SUCCESS : result);
    }

//设置返回结果
    private boolean setValue0(Object objResult) {
        if (RESULT_UPDATER.compareAndSet(this, null, objResult) ||
            RESULT_UPDATER.compareAndSet(this, UNCANCELLABLE, objResult)) {//cas操作设置结果集
            if (checkNotifyWaiters()) {//检查通知等待线程  如果有等待线程 全部唤醒
                notifyListeners();//通知监听器
            }
            return true;
        }
        return false;
    }

 private synchronized boolean checkNotifyWaiters() {
        if (waiters > 0) {//如果有等待线程 则全部唤醒
            notifyAll();//唤醒所有wait阻塞的线程
        }
        return listeners != null;//有监听器则返回true 否则返回false
    }


private void notifyListeners() {//通知所有监听器
        EventExecutor executor = executor();//拿到executor
        if (executor.inEventLoop()) {//如果在事件循环 线程中
            final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get();
            final int stackDepth = threadLocals.futureListenerStackDepth();
            if (stackDepth < MAX_LISTENER_STACK_DEPTH) {
                threadLocals.setFutureListenerStackDepth(stackDepth + 1);
                try {
                    notifyListenersNow();//同步执行notifyListenersNow通知方法
                } finally {
                    threadLocals.setFutureListenerStackDepth(stackDepth);
                }
                return;
            }
        }

        safeExecute(executor, new Runnable() {//异步安全执行 notifyListenersNow通知方法
            @Override
            public void run() {
                notifyListenersNow();
            }
        });
    }


private void notifyListenersNow() {//即刻通知监听器
        Object listeners;
        synchronized (this) {//加锁
            // Only proceed if there are listeners to notify and we are not already notifying listeners.
            if (notifyingListeners || this.listeners == null) {//正在通知中 或者监听器都通知完了
                return;//直接返回
            }
            notifyingListeners = true;//正在通知中标志
            listeners = this.listeners;//设置局部变量listeners
            this.listeners = null;//全局变量的listeners置为空
        }
        for (;;) {
            if (listeners instanceof DefaultFutureListeners) {
                notifyListeners0((DefaultFutureListeners) listeners);//执行通知方法
            } else {
                notifyListener0(this, (GenericFutureListener<?>) listeners);
            }
            synchronized (this) {
                if (this.listeners == null) {//当全局的listeners为空
                    // Nothing can throw from within this method, so setting notifyingListeners back to false does not
                    // need to be in a finally block.
                    notifyingListeners = false;//正在通知表示改回false
                    return;
                }
                listeners = this.listeners;
                this.listeners = null;
            }
        }
    }


private void notifyListeners0(DefaultFutureListeners listeners) {
        GenericFutureListener<?>[] a = listeners.listeners();//拿到所有的监听器对象
        int size = listeners.size();
        for (int i = 0; i < size; i ++) {//循环遍历 执行通知方法
            notifyListener0(this, a[i]);//通知
        }
    }


private static void notifyListener0(Future future, GenericFutureListener l) {
        try {
            l.operationComplete(future);//回调执行所有监听器的operationComplete方法
        } catch (Throwable t) {
            if (logger.isWarnEnabled()) {
                logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationComplete()", t);
            }
        }
    }


public V get() throws InterruptedException, ExecutionException {//重写了get方法 获取到result的返回值
        Object result = this.result;
        if (!isDone0(result)) {//如果没有返回值 则wait阻塞
            await();
            result = this.result;//获取result结果
        }
        if (result == SUCCESS || result == UNCANCELLABLE) {
            return null;
        }
        Throwable cause = cause0(result);
        if (cause == null) {
            return (V) result;
        }
        if (cause instanceof CancellationException) {
            throw (CancellationException) cause;
        }
        throw new ExecutionException(cause);
    }

简单总结:

1、Netty的Promise实现了Future接口,重写了get方法 能够获取线程的返回值

2、netty的promise定义了setSuccess方法 可以主动设置修改返回结果,并且唤醒阻塞线程,并通知所有监听器,执行相关回调方法

3、netty的promise的sync方法可以主动wait当前线程 等待被唤醒

4、netty的DefaultPromise 可以设置监听器对象,等待回调方法被执行

也就是说 netty如果你设置了监听器,  在消息成功发送成功之后 会触发setSuccess的调用 同时会触发所有监听器的方法回调。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值