java.util.concurrent.Future
// 取消异步操作
boolean cancel(boolean mayInterruptIfRunning);
// 异步操作是否取消
boolean isCancelled();
// 异步操作是否完成,正常终止、异常、取消都是完成
boolean isDone();
// 阻塞直到取得异步操作结果
V get() throws InterruptedException, ExecutionException;
// 同上,但最长阻塞时间为timeout
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
举个例子: FutureTask-->RunnableFuture--> Future
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable callable = new Callable(){
@Override
public String call() throws Exception {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "工作做完了";
}
};
FutureTask futureTask = new FutureTask(callable);
new Thread(futureTask).start();
//阻塞或取结果
System.out.println("----"+futureTask.get());
}
netty对future做了扩展
public interface ChannelFuture extends Future {
/**
* Returns a channel where the I/O operation associated with this
* future takes place.
*/
Channel channel();
// 异步操作完成且正常终止
boolean isSuccess();
// 异步操作是否可以取消
boolean isCancellable();
// 异步操作失败的原因
Throwable cause();
// 添加一个监听者,异步操作完成时回调,类比javascript的回调函数
Future addListener(GenericFutureListener extends Future super V>> listener);
Future removeListener(GenericFutureListener extends Future super V>> listener);
// 阻塞直到异步操作完成
Future await() throws InterruptedException;
// 同上,但异步操作失败时抛出异常
Future sync() throws InterruptedException;
// 非阻塞地返回异步结果,如果尚未完成返回null
V getNow();
}
重点看一下
ChannelFuture addListener(GenericFutureListener extends Future super Void>> listener);
public interface GenericFutureListener> extends EventListener {
/**
* Invoked when the operation associated with the {@link Future} has been completed.
*
* @param future the source {@link Future} which called this callback
*/
void operationComplete(F future) throws Exception;
}
这个类相当于执行操作worker , 执行完成后 回调. 对与主线程来说是异步的.
监听器对Future的扩展起到了很灵活的作用,当某个计算完毕,会触发相应的时间,得到Future的结果,因为jdk的get方法我们不知道什么时候去掉好,调早了需要等待,调晚了浪费了一段时间,还有isDone里边有2种情况,无法区分到底是正常的io完毕返回的true还是被取消之后返回的true,所有到了netty的Future里边加了一个isSuccess()方法,只有正常的io处理结束isSuccess()才返回true。
/**
* Listens to the result of a {@link ChannelFuture}. The result of the
* asynchronous {@link Channel} I/O operation is notified once this listener
* is added by calling {@link ChannelFuture#addListener(GenericFutureListener)}.
*
* Return the control to the caller quickly
*
* {@link #operationComplete(Future)} is directly called by an I/O
* thread. Therefore, performing a time consuming task or a blocking operation
* in the handler method can cause an unexpected pause during I/O. If you need
* to perform a blocking operation on I/O completion, try to execute the
* operation in a different thread using a thread pool.
*/
public interface ChannelFutureListener extends GenericFutureListener {
/**
* A {@link ChannelFutureListener} that closes the {@link Channel} which is
* associated with the specified {@link ChannelFuture}.
*/
ChannelFutureListener CLOSE = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
future.channel().close();
}
};
/**
* A {@link ChannelFutureListener} that closes the {@link Channel} when the
* operation ended up with a failure or cancellation rather than a success.
*/
ChannelFutureListener CLOSE_ON_FAILURE = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
future.channel().close();
}
}
};
/**
* A {@link ChannelFutureListener} that forwards the {@link Throwable} of the {@link ChannelFuture} into the
* {@link ChannelPipeline}. This mimics the old behavior of Netty 3.
*/
ChannelFutureListener FIRE_EXCEPTION_ON_FAILURE = new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
future.channel().pipeline().fireExceptionCaught(future.cause());
}
}
};
// Just a type alias
}
@Override
public Future addListener(GenericFutureListener extends Future super V>> listener) {
if (listener == null) {
throw new NullPointerException("listener");
}
DefaultPromise.notifyListener(executor(), this, listener);
return this;
}
看下如何添加监听 DefaultPromise.notifyListener(executor(), this, listener);
追到了DefaultPromise 下面.
//DefaultPromise
private static void notifyListenerWithStackOverFlowProtection(final EventExecutor executor,
final Future> future,
final GenericFutureListener> listener) {
if (executor.inEventLoop()) {
final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get();
final int stackDepth = threadLocals.futureListenerStackDepth();
if (stackDepth < MAX_LISTENER_STACK_DEPTH) {
threadLocals.setFutureListenerStackDepth(stackDepth + 1);
try {
notifyListener0(future, listener);
} finally {
threadLocals.setFutureListenerStackDepth(stackDepth);
}
return;
}
}
safeExecute(executor, new Runnable() {
@Override
public void run() {
notifyListener0(future, listener);
}
});
}
看下safeExecute() 怎么执行的, 哦哦原来是一个线程池.
private static void safeExecute(EventExecutor executor, Runnable task) {
try {
executor.execute(task);
} catch (Throwable t) {
rejectedExecutionLogger.error("Failed to submit a listener notification task. Event loop shut down?", t);
}
}
再看 notifyListener0(future, listener); 原来是手动调用--监听器operationComplete接口方法.
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);
}
}
}
CompleteFuture中定义了executor()
public abstract class CompleteFuture extends AbstractFuture {
private final EventExecutor executor;
/**
* Creates a new instance.
*
* @param executor the {@link EventExecutor} associated with this future
*/
protected CompleteFuture(EventExecutor executor) {
this.executor = executor;
}
/**
* Return the {@link EventExecutor} which is used by this {@link CompleteFuture}.
*/
protected EventExecutor executor() {
return executor;
}
}
https://blog.csdn.net/jiayi_yao/article/details/51046526
promise类似,提供了write的异步回调.
总结: 对future接口做扩展, 通过线程池,异步执行事件监听器实现.