文章目录

Netty 版本:4.1.12.Final



一、​​Future​​简介


​Netty​​​的​​Future​​​是在​​JUC​​​包下的​​Future​​基础上。

主要增加功能:

  1. 添加监听事件
  2. 删除监听事件
@SuppressWarnings("ClassNameSameAsAncestorName")
public interface Future<V> extends java.util.concurrent.Future<V> {

boolean isSuccess();

boolean isCancellable();

// 但IO操作异常时,返回原因,否则为null
Throwable cause();

// 向 Future添加事件,Future完成时,会执行这些事件
Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);

Future<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);

// 移除监听事件
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<V> syncUninterruptibly();

// 等待 Future 完成
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);

// 立即获得结果,如果没有完成,返回null
V getNow();

// 如果成功取消,Future失败,导致 CancellationException
@Override
boolean cancel(boolean mayInterruptIfRunning);
}

【Netty】之 Future(Promise)_Promise

常用类:​​SucceededFuture​​​ ​​FailedFuture​

不需要设置业务逻辑代码,只需要设置成功后的返回和抛出的异常




二、​​Promise​​简介


Future: 业务逻辑所在任务执行的状态(成功或失败)是在 Future 中实现的
Promise:可以在业务逻辑控制任务的执行结果

接口定义如下:

public interface Promise<V> extends Future<V> {
// 设置future执行结果为成功
Promise<V> setSuccess(V result);

// 尝试设置future执行结果为成功,返回是否设置成功
boolean trySuccess(V result);

// 设置失败
Promise<V> setFailure(Throwable cause);

boolean tryFailure(Throwable cause);

// 设置为不能取消
boolean setUncancellable();


// 以下省略了覆盖Future的一些方法
}



(1)举个栗子

public class PromiseTest {

public static void main(String[] args) {

PromiseTest test = new PromiseTest();
NioEventLoopGroup loop = new NioEventLoopGroup();
Promise<String> promise = test.search(loop, "Netty In Action");

promise.addListener(new GenericFutureListener<Future<? super String>>() {
@Override
public void operationComplete(Future<? super String> future) throws Exception {
System.out.println("Listener 1, price is " + future.get());
}

});

loop.shutdownGracefully();
}


private Promise<String> search(NioEventLoopGroup loop, String prod) {

DefaultPromise<String> promise = new DefaultPromise<String>(loop.next());

loop.schedule(new Runnable() {
@Override
public void run() {
System.out.println(String.format(" >>search price of %s from internet!",prod));
promise.setSuccess("$33.33"); // 等待5S后设置future为成功,

}
},0, TimeUnit.SECONDS);

return promise;
}
}

可用​​Promise​​对象,为其设置异步调用完成后的操作。

同时可以继续去做其他任务。



(2)常用​​Promise​​类

有:​​DefaultPromise​​​,​​DefaultChannelPromise​

在​​SingleThreadEventLoop.java​​中运用

public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
promise.channel().unsafe().register(this, promise);
return promise;
}




三、​​Promise​​源码浅析


查看​​DefaultPromise​

【Netty】之 Future(Promise)_Netty_02



(1)​​get()​

调用的是父类 ​​AbstractFuture​

@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);
}



(2)​​await()​

@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 {
// 调用Object.wait(), 阻塞
wait();
} finally {
// 减少等待者
decWaiters();
}
}
}
return this;
}

这里的 ​​sychronized​​ 只是为了同步 增减 waiter



(3)​​addListener()​

@Override
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) listeners).add(listener);
} else {
listeners = new DefaultFutureListeners((GenericFutureListener<?>) listeners, listener);
}
}

这里可以看下 ​​DefaultFutureListeners.java​

感觉这块设计的并不是很好的

Netty版本:4.1.12.Final

它维护了一个数组来保存 ​​listener​

添加/删除操作类似​​ArrayList​

final class DefaultFutureListeners {

private GenericFutureListener<? extends Future<?>>[] listeners;
private int size;
private int progressiveSize; // the number of progressive listeners

@SuppressWarnings("unchecked")
DefaultFutureListeners(
GenericFutureListener<? extends Future<?>> first, GenericFutureListener<? extends Future<?>> second) {
listeners = new GenericFutureListener[2];
listeners[0] = first;
listeners[1] = second;
size = 2;
if (first instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
if (second instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
}

public void add(GenericFutureListener<? extends Future<?>> l) {
GenericFutureListener<? extends Future<?>>[] listeners = this.listeners;
final int size = this.size;
if (size == listeners.length) {
this.listeners = listeners = Arrays.copyOf(listeners, size << 1);
}
listeners[size] = l;
this.size = size + 1;

if (l instanceof GenericProgressiveFutureListener) {
progressiveSize ++;
}
}

public void remove(GenericFutureListener<? extends Future<?>> l) {
final GenericFutureListener<? extends Future<?>>[] listeners = this.listeners;
int size = this.size;
for (int i = 0; i < size; i ++) {
if (listeners[i] == l) {
int listenersToMove = size - i - 1;
if (listenersToMove > 0) {
System.arraycopy(listeners, i + 1, listeners, i, listenersToMove);
}
listeners[-- size] = null;
this.size = size;

if (l instanceof GenericProgressiveFutureListener) {
progressiveSize --;
}
return;
}
}
}

// 。。。
}



(3)​​notifyListeners()​

比如:

  1. 在​​main​​​线程中调用​​addListener()​
  2. ​notifyListeners()​​执行回调,会提交到线程池中执行

内部维护了 ​​notifiyingListeners​​​用来记录是否已经触发过监听事件,只有未触发过且t监听列表不为空,才会依次遍历并调用​​operatingComplete​

private void notifyListeners() {
EventExecutor executor = executor();
if (executor.inEventLoop()) {
// 获取当前线程 map
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();
}
});
}



(4)​​setSuccess()​

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(); // 调用 Object.notfiyAll() 唤醒所有线程
return true;
}
return false;
}



(5)​​cancel()​

@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (RESULT_UPDATER.compareAndSet(this, null, CANCELLATION_CAUSE_HOLDER)) {
// 检查通知等待者,唤醒等待线程
checkNotifyWaiters();
// 通知所有监听者
notifyListeners();
return true;
}
return false;
}