前提
最近一直在看Netty
相关的内容,也在编写一个轻量级的RPC
框架来练手,途中发现了Netty
的源码有很多亮点,某些实现甚至可以用苛刻来形容。另外,Netty
提供的工具类也是相当优秀,可以开箱即用。这里分析一下个人比较喜欢的领域,并发方面的一个Netty
工具模块 - Promise
。
环境版本:
Netty:4.1.44.Final
JDK1.8
Promise简介
Promise,中文翻译为承诺或者许诺,含义是人与人之间,一个人对另一个人所说的具有一定憧憬的话,一般是可以实现的。
io.netty.util.concurrent.Promise
在注释中只有一句话:特殊的可写的io.netty.util.concurrent.Future
(Promise
接口是io.netty.util.concurrent.Future
的子接口)。而io.netty.util.concurrent.Future
是java.util.concurrent.Future
的扩展,表示一个异步操作的结果。我们知道,JDK
并发包中的Future
是不可写,也没有提供可监听的入口(没有应用观察者模式),而Promise
很好地弥补了这两个问题。另一方面从继承关系来看,DefaultPromise
是这些接口的最终实现类,所以分析源码的时候需要把重心放在DefaultPromise
类。一般一个模块提供的功能都由接口定义,这里分析一下两个接口的功能列表:
io.netty.util.concurrent.Promise
io.netty.util.concurrent.Future
先看io.netty.util.concurrent.Future
接口:
public interface Future<V> extends java.util.concurrent.Future<V> {
// I/O操作是否执行成功
boolean isSuccess();
// 标记是否可以通过下面的cancel(boolean mayInterruptIfRunning)取消I/O操作
boolean isCancellable();
// 返回I/O操作的异常实例 - 如果I/O操作本身是成功的,此方法返回null
Throwable cause();
// 为当前Future实例添加监听Future操作完成的监听器 - isDone()方法激活之后所有监听器实例会得到回调
Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
Future<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
// 为当前Future移除监听Future操作完成的监听器
Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
Future<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
// 同步等待Future完成得到最终结果(成功)或者抛出异常(失败),响应中断
Future<V> sync() throws InterruptedException;
// 同步等待Future完成得到最终结果(成功)或者抛出异常(失败),不响应中断
Future<V> syncUninterruptibly();
// 等待Future完成,响应中断
Future<V> await() throws InterruptedException;
// 等待Future完成,不响应中断
Future<V> awaitUninterruptibly();
// 带超时时限的等待Future完成,响应中断
boolean await(long timeout, TimeUnit unit) throws InterruptedException;
boolean await(long timeoutMillis) throws InterruptedException;
// 带超时时限的等待Future完成,不响应中断
boolean awaitUninterruptibly(long timeout, TimeUnit unit);
boolean awaitUninterruptibly(long timeoutMillis);
// 非阻塞马上返回Future的结果,如果Future未完成,此方法一定返回null;有些场景下如果Future成功获取到的结果是null则需要二次检查isDone()方法是否为true
V getNow();
// 取消当前Future实例的执行,如果取消成功会抛出CancellationException异常
@Override
boolean cancel(boolean mayInterruptIfRunning);
}
sync()
和await()
方法类似,只是sync()
会检查异常执行的情况,一旦发现执行异常马上把异常实例包装抛出,而await()
方法对异常无感知。
接着看io.netty.util.concurrent.Promise
接口:
public interface Promise<V> extends Future<V> {
// 标记当前Future成功,设置结果,如果设置成功,则通知所有的监听器,如果Future已经成功或者失败,则抛出IllegalStateException
Promise<V> setSuccess(V result);
// 标记当前Future成功,设置结果,如果设置成功,则通知所有的监听器并且返回true,否则返回false
boolean trySuccess(V result);
// 标记当前Future失败,设置结果为异常实例,如果设置成功,则通知所有的监听器,如果Future已经成功或者失败,则抛出IllegalStateException
Promise<V> setFailure(Throwable cause);
// 标记当前Future失败,设置结果为异常实例,如果设置成功,则通知所有的监听器并且返回true,否则返回false
boolean tryFailure(Throwable cause);
// 标记当前的Promise实例为不可取消,设置成功返回true,否则返回false
boolean setUncancellable();
// 下面的方法和io.netty.util.concurrent.Future中的方法基本一致,只是修改了返回类型为Promise
@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();
}
到此,Promise
接口的所有功能都分析完毕,接下来从源码角度详细分析Promise
的实现。
Promise源码实现
Promise
的实现类为io.netty.util.concurrent.DefaultPromise
(其实DefaultPromise
还有很多子类,某些实现是为了定制特定的场景做了扩展),而DefaultPromise
继承自io.netty.util.concurrent.AbstractFuture
:
public abstract class AbstractFuture<V> implements Future<V> {
// 永久阻塞等待获取结果的方法
@Override
public V get() throws InterruptedException, ExecutionException {
// 调用响应中断的永久等待方法进行阻塞
await();
// 从永久阻塞中唤醒后,先判断Future是否执行异常
Throwable cause = cause();
if (cause == null) {
// 异常为空说明执行成功,调用getNow()方法返回结果
return getNow();
}
// 异常为空不为空,这里区分特定的取消异常则转换为CancellationException抛出
if (cause instanceof CancellationException) {
throw (CancellationException) cause;
}
// 非取消异常的其他所有异常都被包装为执行异常ExecutionException抛出
throw new ExecutionException(cause);
}
// 带超时阻塞等待获取结果的方法
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
// 调用响应中断的带超时时限等待方法进行阻塞
if (await(timeout, unit)) {
// 从带超时时限阻塞中唤醒后,先判断Future是否执行异常
Throwable cause = cause();
if (cause == null) {
// 异常为空说明执行成功,调用getNow()方法返回结果
return getNow();
}
// 异常为空不为空,这里区分特定的取消异常则转换为CancellationException抛出
if (cause instanceof CancellationException) {
throw (CancellationException) cause;
}
// 在非等待超时的前提下,非取消异常的其他所有异常都被包装为执行异常ExecutionException抛出
throw new ExecutionException(cause);
}
// 方法步入此处说明等待超时,则抛出超时异常TimeoutException
throw new TimeoutException();
}
}
AbstractFuture
仅仅对get()
和get(long timeout, TimeUnit unit)
两个方法进行了实现,其实这两处的实现和java.util.concurrent.FutureTask
中的实现方式十分相似。
DefaultPromise
的源码比较多,这里分开多个部分去阅读,先看它的属性和构造函数:
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
// 正常日志的日志句柄,InternalLogger是Netty内部封装的日志接口
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultPromise.class);
// 任务拒绝执行时候的日志句柄 - Promise需要作为一个任务提交到线程中执行,如果任务拒绝则使用此日志句柄打印日志
private static final InternalLogger rejectedExecutionLogger =
InternalLoggerFactory.getInstance(DefaultPromise.class.getName() + ".rejectedExecution");
// 监听器的最大栈深度,默认值为8,这个值是防止嵌套回调调用的时候栈深度过大导致内存溢出,后面会举个例子说明它的用法
private static final int MAX_LISTENER_STACK_DEPTH = Math.min(8,
SystemPropertyUtil.getInt("io.netty.defaultPromise.maxListenerStackDepth", 8));
// 结果更新器,用于CAS更新结果result的值
@SuppressWarnings("rawtypes")
private static final AtomicReferenceFieldUpdater<DefaultPromise, Object> RESULT_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(DefaultPromise.class, Object.class, "result");
// 用于填充result的值,当设置结果result传入null,Promise执行成功,用这个值去表示成功的结果
private static final Object SUCCESS = new Object();
// 用于填充result的值,表示Promise不能被取消
private static final Object UNCANCELLABLE = new Object();
// CancellationException实例的持有器,用于判断Promise取消状态和抛出CancellationException
private static final CauseHolder CANCELLATION_CAUSE_HOLDER = new CauseHolder(ThrowableUtil.unknownStackTrace(
new CancellationException(), DefaultPromise.class, "cancel(...)"));
// CANCELLATION_CAUSE_HOLDER的异常栈信息元素数组
private static final StackTraceElement[] CANCELLATION_STACK = CANCELLATION_CAUSE_HOLDER.cause.getStackTrace();
// 真正的结果对象,使用Object类型,最终有可能为null、真正的结果实例、SUCCESS、UNCANCELLABLE或者CANCELLATION_CAUSE_HOLDER等等
private volatile Object result;
// 事件执行器,这里暂时不做展开,可以理解为单个调度线程
private final EventExecutor executor;
// 监听器集合,可能是单个GenericFutureListener实例或者DefaultFutureListeners(监听器集合)实例
private Object listeners;