概述
promise 是可寫的 future, 因爲 future 不支持寫操作接口,netty 使用 promise 擴展了 future, 可以對異步操作結果進行設置。
DefaultPromise 繼承關係
Promise 接口定義
從接口定義可以看出,Promise 在 Future 接口的基礎上擴展了,可寫的接口。比如 setSuccess()、setFailure() 接口。還支持添加 listener,當執行完成 Promise 後自動回調添加的 listener,這樣就不用再通過 get 阻塞的方式進行處理,提高執行效率。
DefaultPromise 成員變量
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
// 使用 CAS 進行更新執行結果 result 字段。
private static final AtomicReferenceFieldUpdater<DefaultPromise, Object> RESULT_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(DefaultPromise.class, Object.class, "result");
// result 的幾種 value
private static final Object SUCCESS = new Object();
private static final Object UNCANCELLABLE = new Object();
private static final CauseHolder CANCELLATION_CAUSE_HOLDER = new CauseHolder(ThrowableUtil.unknownStackTrace(
new CancellationException(), DefaultPromise.class, "cancel(...)"));
// 存儲執行結果的變量
private volatile Object result;
// 執行的線程池
private final EventExecutor executor;
DefaultPromise 是通過 CAS 來進行更新執行的結果 result 字段的。
如果執行完成,無返回值則 result = SUCCESS。 有返回值則 result = 執行結果。
如果執行未完成,result = UNCANCELLABLE。
如果執行異常,result = CANCELLATION_CAUSE_HOLDER。
設置執行成功結果
@Override
public Promise<V> setSuccess(V result) {
if (setSuccess0(result)) {
notifyListeners();
return this;
}
throw new IllegalStateException("complete already: " + this);
}
1、調用 setSuccess0() 方法設置執行結果
2、如果設置成功則執行 所有通過addListener(GenericFutureListener<? extends Future<? super V>> listener)
方法添加的 listener,並返回當前的 Promise。
3、執行失敗拋出 IllegalStateException 異常
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)) {
checkNotifyWaiters();
return true;
}
return false;
}
private synchronized void checkNotifyWaiters() {
if (waiters > 0) {
notifyAll();
}
}
1、如果 result == null 則設置爲 SUCCESS,然後調用 setValue0() 方法
2、通過 CAS 設置 DefaultPromise.result 值, 判斷result 是否爲 null 或者 UNCANCELLABLE,如果是則進行修改。如果不是說明已經執行完成(可能成功或失敗)。然後調用checkNotifyWaiters() 方法進行喚醒所有 調用 DefaultPromise.get() 獲取結果的線程。
3、根據 waiters 進行判斷是否有需要喚醒的線程。每一次調用 get() 獲取Promise執行結果的時候都會調用 incWaiters() 方法 ++waiters,執行完後調用 decWaiters() 進行 --waiters。
private void notifyListeners() {
EventExecutor 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();
} finally {
threadLocals.setFutureListenerStackDepth(stackDepth);
}
return;
}
}
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyListenersNow();
}
});
}
獲取 EventExecutor ,其實就是 EventLoop,判斷執行 EventExecutor 的線程是否和當前線程一致,如果一致則調用 notifyListenersNow() 方法執行 listener。不一致則將任務封裝成 Runnable 提交到任務隊列中等待執行。
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;
this.listeners = null;
}
for (;;) {
if (listeners instanceof DefaultFutureListeners) {
notifyListeners0((DefaultFutureListeners) listeners);
} else {
notifyListener0(this, (GenericFutureListener<?>) listeners);
}
synchronized (this) {
if (this.listeners == null) {
// Nothing can throw from within this method, so setting notifyingListeners back to false does not
// need to be in a finally block.
notifyingListeners = false;
return;
}
listeners = this.listeners;
this.listeners = null;
}
}
}
1、獲取 listeners 值 並將 this.listeners 置爲 null
listeners = this.listeners;
this.listeners = null;
2、調用 notifyListeners0() 或 notifyListener0() 方法執行 listeners
3、執行完 listeners 後,再次判斷 this.listeners 是否爲null,如果不爲null,說明在執行過程中又有新的 listeners 添加進來,繼續 for 循環執行。如果爲 null 則return 退出 死循環。
private void notifyListeners0(DefaultFutureListeners listeners) {
GenericFutureListener<?>[] a = listeners.listeners();
int size = listeners.size();
for (int i = 0; i < size; i ++) {
notifyListener0(this, a[i]);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void notifyListener0(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);
}
}
}
執行添加的 listeners。
獲取執行結果
@Override
public V get() throws InterruptedException, ExecutionException {
await();
Throwable cause = cause();
if (cause == null) {
return getNow();
}
if (cause instanceof CancellationException) {
throw (CancellationException) cause;
}
throw new ExecutionException(cause);
}
1、首先判斷該 Promise 是否執行完成,如果執行完成則繼續執行,如果沒有執行完成則掛起當前線程。
2、判斷執行是否有異常,如果沒有異常則直接調用 getNow() 方法獲取返回值。
3、如果有異常則首先判斷異常是否是 CancellationException異常,如果是則直接拋出,不是則使用 ExecutionException 異常包裝再拋出。
@Override
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;
}
1、通過 isDone() 方法判斷是否執行完成,如果執行完成直接返回
2、判斷當前線程是否被中斷,如果中斷則直接拋出 InterruptedException 異常
3、檢查執行 Promise 任務的線程是否是當前線程,如果是當前線程再調用 await() 就會發生死鎖的情況,拋出 BlockingOperationException 異常。就相當於獲取結果和執行都是當前線程,自己調用 await() 方法把自己阻塞掉了。
@SuppressWarnings("unchecked")
@Override
public V getNow() {
Object result = this.result;
if (result instanceof CauseHolder || result == SUCCESS || result == UNCANCELLABLE) {
return null;
}
return (V) result;
}
如果 Promise 執行無返回結果,當執行完成時會把 result 設置爲 SUCCESS,這裏判斷如果有異常、SUCCESS 和 UNCANCELLABLE 則返回 null,否則返回執行結果 result。