JavaFuture源码分析与Netty提供的Future与ChannelFuture优势分析与源码分析

javaFuture源码分析与Netty提供的Future与ChannelFuture优势分析与源码分析

    • 既然是源码分析那么免不了要看源码从哪儿看呢? 当然是JDK1.5Future
      • 总结:其实可以很清楚的了解到,这些dk1.5里面所引入的future这个接口它主要的作用就是封装异步计算的一个结果并且提供了方法来去中断或者取消任务的执行,并且提供了一些返回布尔值的一些方法,来去判断这个任务呢是不是被取消了啊,任务呢是不是被完成了然后呢最重要的。提供了相应的get()方法来获取结果以异步的方式通
        • 我们在简单看一下Netty提供的Future
      • 两个Future对比 :
        • channelFuture的源码注释

既然是源码分析那么免不了要看源码从哪儿看呢? 当然是JDK1.5Future

ChannelFuture继承了future所以我们从
JDK1.5源码Future分析源码如下

future,它代表的是一个result呢。总的来说就是,一个future,它代表的是一个异步的计算的结果,一个future代表的是异步计算的,它的结果同步计算的结果。调完之后执行完了我们就拿到了,那么异步因为就是因为异步所以呢他的结果不是立刻就返回来了那么,gd k1.5呢通过一个非true对象来封装这个异步计算的,这是future的一个总体的含义。然后呢,这个future本身它提供了若干个方法来去检查,这个计算是不是已经完成了,并且还会去通过一些方法呢来去等待。这个计算的完成并且,还提供了若干个方法来去获取的计算的什么结果,那这个其实我们接口里面的这几个方法他所完成的事情。

/**
 * A {@code Future} represents the result of an asynchronous
 * computation.  Methods are provided to check if the computation is
 * complete, to wait for its completion, and to retrieve the result of
 * the computation.  The result can only be retrieved using method
 * {@code get} when the computation has completed, blocking if
 * **通过GET方法来阻塞的方法来获取结果**
 * necessary until it is ready.  Cancellation is performed by the
 * {@code cancel} method.  Additional methods are provided to
 * determine if the task completed normally or was cancelled. Once a
 * computation has completed, the computation cannot be cancelled.
 * 
 * If you would like to use a {@code Future} for the sake
 * of cancellability but not provide a usable result, you can
 * declare types of the form {@code Future} and
 * return {@code null} as a result of the underlying task. 
 * **如果呢你希望使用future打针对于什么的。针对于,取消这个目的然后然后呢去提供一个future但是呢又没有提供一个可用的结果那么呢你就可以声明Future}形式的future然后呢,返回一个空作为底层任务的一个结果。**
 * 
 * 
 *
 * 

* Sample Usage (Note that the following classes are all * made-up.) *

 {@code
 *       **示例**
 * interface ArchiveSearcher { String search(String target); }
 * class App {
 *   ExecutorService executor = ...
 *   ArchiveSearcher searcher = ...
 *   void showSearch(final String target)
 *       throws InterruptedException {
 * 		**声明对象**
 *     Future future 
 *    **定义了一个结果 Callable返回String泛型 将Callable里面的任务提交给了submit这个方法 最后**
 *       = executor.submit(new Callable() {
 *         public String call() {
 * 			**定了一个搜索方法**
 *             return searcher.search(target);
 *         }}); 
 * **做其他的事情 做一些其他的事情呢换句话说这个搜索呢可能是一个比较耗时的这么一个,操作他把这个任务呢,提交给了submit的方法之后呢,流程继续的去往下执行而不必等这个结果呢去返回。就是这个动作本身还会继续的去执行然后呢,主线程,距往下执行紧接着,那么我如何获取到这个,return之后的结果呢,是这样的有一个display text方法呢future.get()方法返回真正的结果。**
 *     displayOtherThings(); // do other things while searching
 *     try {
 *       displayText(future.get()); // use future
 *     } catch (ExecutionException ex) { cleanup(); return; }
 *   }
 * }}
* * The {@link FutureTask} class is an implementation of {@code Future} that * implements {@code Runnable}, and so may be executed by an {@code Executor}. * For example, the above construction with {@code submit} could be replaced by: **这个FutureTask类呢,它是一个future的实现那么它本身,呢实现了Runnable比如说他给他实现了,接口也继承了future,基层的标准所以呢,我们看到的FutureTask了,他既继承了future也继承了rainbow实现实现了future所以呢,这个FutureTask类他就是future的一个实现并且呢它也实现了Runnable因此,呢他可以通过一个executed 来去执行** *
 {@code
 * FutureTask future =
 *   new FutureTask(new Callable() {
 *     public String call() {
 *       return searcher.search(target);
 *   }}); 
 * ** 真正的执行**
 * executor.execute(future);}
* **看内存一致性的影响** *

Memory consistency effects: Actions taken by the asynchronous computation * happen-before * actions following the corresponding {@code Future.get()} in another thread. * **异步计算,他的这个动作一定是发生在另一个线程里面的future.get()方法所返回来的** * @see FutureTask * @see Executor * @since 1.5 * @author Doug Lea * @param The result type returned by this Future's {@code get} method */ public interface Future { /** * Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, has already been cancelled, * or could not be cancelled for some other reason. If successful, * and this task has not started when {@code cancel} is called, * this task should never run. If the task has already started, * then the {@code mayInterruptIfRunning} parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task. * *

After this method returns, subsequent calls to {@link #isDone} will * always return {@code true}. Subsequent calls to {@link #isCancelled} * will always return {@code true} if this method returned {@code true}. * * @param mayInterruptIfRunning {@code true} if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete * @return {@code false} if the task could not be cancelled, * typically because it has already completed normally; * {@code true} otherwise */ **这个方法这个方法是取消这个任务的执行是尝试着呢去取消这个任务的执行那么这种尝试呢,如果这个任务已经完成的话这个尝试就失败了** boolean cancel(boolean mayInterruptIfRunning); /** * Returns {@code true} if this task was cancelled before it completed * normally. * * @return {@code true} if this task was cancelled before it completed */ boolean isCancelled(); /** * Returns {@code true} if this task completed. * * Completion may be due to normal termination, an exception, or * cancellation -- in all of these cases, this method will return * {@code true}. * * @return {@code true} if this task completed */ **完成返回true** boolean isDone(); /** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return the computed result * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an * exception * @throws InterruptedException if the current thread was interrupted * while waiting */ V get() throws InterruptedException, ExecutionException; /** * Waits if necessary for at most the given time for the computation * to complete, and then retrieves its result, if available. * * @param timeout the maximum time to wait * @param unit the time unit of the timeout argument * @return the computed result * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an * exception * @throws InterruptedException if the current thread was interrupted * while waiting * @throws TimeoutException if the wait timed out */ V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }

总结:其实可以很清楚的了解到,这些dk1.5里面所引入的future这个接口它主要的作用就是封装异步计算的一个结果并且提供了方法来去中断或者取消任务的执行,并且提供了一些返回布尔值的一些方法,来去判断这个任务呢是不是被取消了啊,任务呢是不是被完成了然后呢最重要的。提供了相应的get()方法来获取结果以异步的方式通

我们在简单看一下Netty提供的Future

public interface Future extends java.util.concurrent.Future {

    /**
     * Returns {@code true} if and only if the I/O operation was completed
     * 判断任务完成 successfully.
     */
    boolean isSuccess();

    /**
     * returns {@code true} if and only if the operation can be cancelled via {@link #cancel(boolean)}.
 **判断cancel方法是否成功**
     */
    boolean isCancellable();

    /**
     * Returns the cause of the failed I/O operation if the I/O operation has
     * failed.
     *
     * @return the cause of the failure.
     *         {@code null} if succeeded or this future is not
     *         completed yet.
 **如果失败返回失败的方法**
     */
    Throwable cause();

    /**
     * Adds the specified listener to this future.  The
     * specified listener is notified when this future is
     * {@linkplain #isDone() done}.  If this future is already
     * completed, the specified listener is notified immediately. 
** 向这个future去添加了指定的listener,是当这个future一旦方法完成的话,这个指定的listener呢就会收到通知如果。the future已经完成的话那么指定listener就会立刻的被通知到,实际上,这里面它实际上用到了一种叫观察者模式这样的一种设计模式。以后我们但凡见到什么什么...listener那都是会用到观察者模式那换句话说,呢我们这里面大家,注意我们这里面是往Future对象里面可以添加这个listener的**
     */
    Future addListener(GenericFutureListener> listener);

    /**
     * Adds the specified listeners to this future.  The
     * specified listeners are notified when this future is
     * {@linkplain #isDone() done}.  If this future is already
     * completed, the specified listeners are notified immediately.
     */
    Future addListeners(GenericFutureListener>... listeners);

    /**
     * Removes the first occurrence of the specified listener from this future.
     * The specified listener is no longer notified when this
     * future is {@linkplain #isDone() done}.  If the specified
     * listener is not associated with this future, this method
     * does nothing and returns silently.
     */
    Future removeListener(GenericFutureListener> listener);

    /**
     * Removes the first occurrence for each of the listeners from this future.
     * The specified listeners are no longer notified when this
     * future is {@linkplain #isDone() done}.  If the specified
     * listeners are not associated with this future, this method
     * does nothing and returns silently.
     */
    Future removeListeners(GenericFutureListener>... listeners);

    /**
     * Waits for this future until it is done, and rethrows the cause of the failure if this future
 **他是等待这个future直到future完成那这个方法是同步的**
     */
    Future sync() throws InterruptedException;

    /**
     * Waits for this future until it is done, and rethrows the cause of the failure if this future
     * failed.
     */
    Future syncUninterruptibly();

    /**
     * Waits for this future to be completed.
     *
     * @throws InterruptedException
     *         if the current thread was interrupted
     */
    Future await() throws InterruptedException;

    /**
     * Waits for this future to be completed without
     * interruption.  This method catches an {@link InterruptedException} and
     * discards it silently.
     */
    Future awaitUninterruptibly();

    /**
     * Waits for this future to be completed within the
     * specified time limit.
     *
     * @return {@code true} if and only if the future was completed within
     *         the specified time limit
     *
     * @throws InterruptedException
     *         if the current thread was interrupted
     */
    boolean await(long timeout, TimeUnit unit) throws InterruptedException;

    /**
     * Waits for this future to be completed within the
     * specified time limit.
     *
     * @return {@code true} if and only if the future was completed within
     *         the specified time limit
     *
     * @throws InterruptedException
     *         if the current thread was interrupted
     */
    boolean await(long timeoutMillis) throws InterruptedException;

    /**
     * Waits for this future to be completed within the
     * specified time limit without interruption.  This method catches an
     * {@link InterruptedException} and discards it silently.
     *
     * @return {@code true} if and only if the future was completed within
     *         the specified time limit
     */
    boolean awaitUninterruptibly(long timeout, TimeUnit unit);

    /**
     * Waits for this future to be completed within the
     * specified time limit without interruption.  This method catches an
     * {@link InterruptedException} and discards it silently.
     *
     * @return {@code true} if and only if the future was completed within
     *         the specified time limit
     */
    boolean awaitUninterruptibly(long timeoutMillis);

    /**
     * Return the result without blocking. If the future is not done yet this will return {@code null}.
     *
     * As it is possible that a {@code null} value is used to mark the future as successful you also need to check
     * if the future is really done with {@link #isDone()} and not relay on the returned {@code null} value.
**获取状态,如果成功了返回Null 但是不推荐通过Null来判断结果,同时还有通过isDone来判断**
     */
    V getNow();

    /**
     * {@inheritDoc}
     *
     * If the cancellation was successful it will fail the future with an {@link CancellationException}.
     */
    @Override
    boolean cancel(boolean mayInterruptIfRunning);
}

其他没注释的方法应该从字面就可以看清楚,就不做过多的解释

两个Future对比 :

**JDK所提供的Future只能通过手工的方式检查执行结果,而这个操作时会阻塞的Netty则对ChannelFuture进行了增强,通过ChannelFutureListener以回调的方式来获取执行结果,去除了手工检查阻塞的操作。
JDK isDone() 无法判断执行结果 完成了(因为异常?或者正常?无法判断?) Netty isSuccess()却可以判断() 是 isDone()一种情况
Netty通过Listener来判断执行结果, 观察者模式 监听器自动的拿到我的结果可用性更好
**

channelFuture的源码注释

在这里会简单的介绍里面的几个方法但是重要的还是理解里面写的注释的意思
概念: 这个channel afuture顾名思义就是针对于channel的未来对象他表示的是一个异步的channel io操作的结果你可以看到,对于jdk1.5内future它是一个非常通用的广泛的future。然后Netty提供了future的对它进行了一些特化然后呢,Netty也有提供了hannel只有这是专门针对channel io操作的这样一个未来对象他表示这个channel io操作的一个异步的执行结果

/**
 * The result of an asynchronous {@link Channel} I/O operation.
 * 

* All I/O operations in Netty are asynchronous. It means any I/O calls will * return immediately * 所有的io操作全都是异步,的内地当中所有的,io操作全都是异步的那么这,意味着任何io的调用都会立即返回 * with no guarantee that the requested I/O operation has * been completed at the end of the call. Instead, you will be returned with * a {@link ChannelFuture} instance which gives you the information about the * result or status of the I/O operation. * *

* A {@link ChannelFuture} is either uncompleted or completed. * When an I/O operation begins, a new future object is created. The new future * is uncompleted initially - it is neither succeeded, failed, nor cancelled * because the I/O operation is not finished yet. If the I/O operation is * finished either successfully, with failure, or by cancellation, the future is * marked as completed with more specific information, such as the cause of the * failure. Please note that even failure and cancellation belong to the * completed state. *

 *                                      +---------------------------+
 *                                      | Completed successfully 成功完成   |
 *                                      +---------------------------+
 *                                 +---->      isDone() = true      |
 * +--------------------------+    |    |   isSuccess() = true      |
 * |        Uncompleted  未完成     |    |    +===========================+
 * +--------------------------+    |    | Completed with failure   失败完成 |
 * |      isDone() = false    |    |    +---------------------------+
 * |   isSuccess() = false    |----+---->      isDone() = true      |
 * | isCancelled() = false    |    |    |       cause() = non-null  |
 * |       cause() = null     |    |    +===========================+
 * +--------------------------+    |    | Completed by cancellation 取消的话 |
 *                                 |    +---------------------------+
 *                                 +---->      isDone() = true      |
 *                                      | isCancelled() = true      |
 *                                      +---------------------------+
 * 
* 有三种状态并且,对于三种结果更加的细化 * * Various methods are provided to let you check if the I/O operation has been * completed, wait for the completion, and retrieve the result of the I/O * operation. It also allows you to add {@link ChannelFutureListener}s so you * can get notified when the I/O operation is completed. * channel future会提供了各种方法让你去可以检查,这个io操作是不是已经完成了,还是在等待完成,并且呢可以获取到i o操作的什么的结果那么它才可以让你们去添加addListener(GenericFutureListener)}这样的话呢,当,i o操作完成的时候你就可以收到通知了 * *

Prefer {@link #addListener(GenericFutureListener)} to {@link #await()}

*建议使用addListener不是await * It is recommended to prefer {@link #addListener(GenericFutureListener)} to * {@link #await()} wherever possible to get notified when an I/O operation is * done and to do any follow-up tasks. *

* addListener方法,它是一个非阻塞的,它仅仅是向指定的,Channel * {@link #addListener(GenericFutureListener)} is non-blocking. It simply adds * the specified {@link ChannelFutureListener} to the {@link ChannelFuture}, and * 完成的时候就会通知 * I/O thread will notify the listeners when the I/O operation associated with * the future is done. {@link ChannelFutureListener} yields the best * performance and resource utilization because it does not block at all, but * 产生最好的性能。和资源利用率,因为,那他什么都不会阻塞不过呢可能很棘手的去实现一个顺序的逻辑如果呢你还不了解事件驱动的这种编程的话啊。 * it could be tricky to implement a sequential logic if you are not used to * event-driven programming. *

* 阻塞的操作一旦被调用那么调用者线程呢就会卡住就会就会停下来直到操作完成那么。 那么对于,这个wait()的方法来说实现一种顺序的逻辑呢是比较容易的但是调用者线程的会没必要的就阻塞直到l操作的完成然后呢这个成本的是比较高的 * By contrast, {@link #await()} is a blocking operation. Once called, the * caller thread blocks until the operation is done. It is easier to implement * a sequential logic with {@link #await()}, but the caller thread blocks * unnecessarily until the I/O operation is done and there's relatively * expensive cost of inter-thread notification. Moreover, there's a chance of * 在意某些特定的环境下出现一种在lock死锁的 * dead lock in a particular circumstance, which is described below. *不要在ChannelHandler 里面调用await方法 *

Do not call {@link #await()} inside {@link ChannelHandler}

*

线程当然是处理输入输出了I/O thread,那么如果如果这个await的方法是在事件处理器当中,所调用的那么, 事件处理器是什么?比如说 连接上了。断开了等等事件,那么这个就是事件处理器方法, 那么如果我们调用了这个await的方法的话,后面的这个事件处理器方法是被IO线程所调用的对吧?那么如果存在这种情况这样的话等待的这个IO操作可能永远不会完成,永远不会因为什么,因为await方法本身会阻塞这个IO操作,await的方法本身会阻塞 * The event handler methods in {@link ChannelHandler} are usually called by * an If {@link #await()} is called by an event handler * method, which is called by the I/O thread, the I/O operation it is waiting * for might never complete because {@link #await()} can block the I/O * operation it is waiting for, which is a dead lock. *

 * // BAD - NEVER DO THIS 反例
 * {@code @Override}
 * public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
 *     {@link ChannelFuture} future = ctx.channel().close();
 *     future.awaitUninterruptibly();
 *     // Perform post-closure operation
 *     // ...
 * }
 *
 * // GOOD
 * {@code @Override} 正例: 
 * public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
 *     {@link ChannelFuture} future = ctx.channel().close();
 *     future.addListener(new {@link ChannelFutureListener}() {
 *         public void operationComplete({@link ChannelFuture} future) {
 *             // Perform post-closure operation
 *             // ...
 *         }
 *     });
 * }
 * 
*

* 请确保你不要在一个IO线程里面去调用的方法,否则。否则就会出现一个block operation一场来去防止一个死锁的发生OK, * In spite of the disadvantages mentioned above, there are certainly the cases * where it is more convenient to call {@link #await()}. In such a case, please * make sure you do not call {@link #await()} in an I/O thread. Otherwise, * {@link BlockingOperationException} will be raised to prevent a dead lock. *不要将IO超时和等待超时混为一谈 *

Do not confuse I/O timeout and await timeout

* * The timeout value you specify with {@link #await(long)}, * {@link #await(long, TimeUnit)}, {@link #awaitUninterruptibly(long)}, or * {@link #awaitUninterruptibly(long, TimeUnit)} are not related with I/O * timeout at all. If an I/O operation times out, the future will be marked as * 'completed with failure,' as depicted in the diagram above. For example, * 连接超时 * connect timeout should be configured via a transport-specific option: *
 * // BAD - NEVER DO THIS
 * {@link Bootstrap} b = ...;
 * //配置等待超时 
 * {@link ChannelFuture} f = b.connect(...);
 * f.awaitUninterruptibly(10, TimeUnit.SECONDS);
 * if (f.isCancelled()) {
 * 取消了连接
 *     // Connection attempt cancelled by user
 * } else if (!f.isSuccess()) {
 * 可能得到一个空指针 因为  * {@link ChannelFuture} f = b.connect(...); 返回一个future 可能没能完成了连接 
 *     // You might get a NullPointerException here because the future
 *     // might not be completed yet.
 *     f.cause().printStackTrace();
 * } else {
 *     // Connection established successfully
 * }
 *
 * // GOOD
 * {@link Bootstrap} b = ...;
 * // Configure the connect timeout option. 
 * //设定超时完成 如果10没连接上那么就是超时了
 * b.option({@link ChannelOption}.CONNECT_TIMEOUT_MILLIS, 10000);
 * 
 * {@link ChannelFuture} f = b.connect(...);
 * //等待链接完成
 * f.awaitUninterruptibly();
 *
 * // Now we are sure the future is completed.
 * assert f.isDone();
 *
 * if (f.isCancelled()) {
 *     // Connection attempt cancelled by user
 * } else if (!f.isSuccess()) {
 *     f.cause().printStackTrace();
 * } else {
 *     // Connection established successfully
 * }
 * 
*/
 *                                      +---------------------------+
 *                                      | Completed successfully 成功完成   |
 *                                      +---------------------------+
 *                                 +---->      isDone() = true      |
 * +--------------------------+    |    |   isSuccess() = true      |
 * |        Uncompleted  未完成     |    |    +===========================+
 * +--------------------------+    |    | Completed with failure   失败完成 |
 * |      isDone() = false    |    |    +---------------------------+
 * |   isSuccess() = false    |----+---->      isDone() = true      |
 * | isCancelled() = false    |    |    |       cause() = non-null  |
 * |       cause() = null     |    |    +===========================+
 * +--------------------------+    |    | Completed by cancellation 取消的话 |
 *                                 |    +---------------------------+
 *                                 +---->      isDone() = true      |
 *                                      | isCancelled() = true      |
 *                                      +---------------------------+
 * 

一个方法的状态一定要理解清楚,首先是连接没有完成,然后呢是已经完成了失败了,并且呢,还有一个是取消了,那么在三种状态之下啊,在这个三种状态之下,那么每一个方法会反回?什么样的结果?也就是上面的那种情况

你可能感兴趣的:(JAVA,future)