我们查看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的调用 同时会触发所有监听器的方法回调。