Netty源码分析:ChannelFuture与Future底层解析

继承关系

io.netty.channel.ChannelFuture extends io.netty.util.concurrent.Future extends java.util.concurrent.Future

java.util.concurrent.Future

JDK1.5新增的接口,Future表示的是一个异步执行的结果。

当一个主线程中存在一个耗时较长的操作时候,可以异步的来处理这个操作,即放在线程池中,主线程继续往下执行,在未来的某个时刻,通过Future来获得这个异步操作的执行结果。

提供如下方法供开发者监控并操作异步执行任务

  • boolean cancel(boolean mayInterruptIfRunning);
  • boolean isCancelled();
  • boolean isDone();
  • V get() throws InterruptedException, ExecutionException;
  • V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

特别需要注意的是 get() 方法,get()是阻塞的,直到异步任务执行完毕并返回执行结果V get(long timeout, TimeUnit unit) 会阻塞到指定的timeout时间

    /**
     * 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;

Future Java Doc使用示例:

 * <p>
 * <b>Sample Usage</b> (Note that the following classes are all
 * made-up.)
 * <pre> {@code
 * interface ArchiveSearcher { String search(String target); }
 * class App {
 *   ExecutorService executor = ...
 *   ArchiveSearcher searcher = ...
 *   void showSearch(final String target)
 *       throws InterruptedException {
 *     Future<String> future
 *       = executor.submit(new Callable<String>() {
 *         public String call() {
 *             return searcher.search(target);
 *         }});
 *     displayOtherThings(); // do other things while searching
 *     try {
 *       displayText(future.get()); // use future
 *     } catch (ExecutionException ex) { cleanup(); return; }
 *   }
 * }}</pre>
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class TestFutureTask {
	public static void main(String[] args) throws InterruptedException,
			ExecutionException {
		final ExecutorService exec = Executors.newFixedThreadPool(5);
		Callable<String> call = new Callable<String>() {
			public String call() throws Exception {
				Thread.sleep(1000 * 3);//休眠指定的时间,此处表示该操作比较耗时
				return "Other less important but longtime things.";
			}
		};
		Future<String> task = exec.submit(call);
		//主线程继续执行
		Thread.sleep(1000 * 3);
		System.out.println("Let's do important things.");
		//获取异步操作的执行结果
		String obj = task.get();
		System.out.println(obj);
		//关闭线程池
		exec.shutdown();
	}
}

Callable 类似于 Runnable,只不过Callable是有返回值的。

io.netty.util.concurrent.Future

可以理解为升级版的Java Futute,主要升级点在listener(监听器)功能

可以向Future添加指定的listener,当Future对应的异步任务完成时候,会通知指定的listener,当Future已经是完成状态的时候会立即通知指定的listener。一种典型的观察者模式。

在获取Future返回结果的时候尽量使用listener,不要使用await,await方法是阻塞的,在Netty中是以事件驱动为核心的异步思想

Netty为什么要拓展Java Future呢?

起始Java Future的设计初衷是极好的,但是存在一个非常尴尬的问题,那就是我们什么时候去调用Future.get()方法获取异步执行结果呢?

我们只是创建了一个异步的任务在主线程外执行,但是!它什么时候执行完成我们是不知道的,也就是说我们调用get()方法去获取异步执行结果的时候会有两种情况:

  1. 异步执行还没有结束,代码阻塞,等待异步执行结束并返回结果
  2. 异步执行结束了,直接返回了结果

出现第2种情况我们还能接受,毕竟没有阻塞代码,但是出现第1种情况的时候就非常尴尬了,JDK原生的Future并没有完全解决异步执行的结果获取问题!这样的情况在Netty中肯定是不被接受的,所以就出现了Netty Future中listener的设计。

/*
 * Copyright 2013 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.util.concurrent;

import java.util.EventListener;

/**
 * Listens to the result of a {@link Future}.  The result of the asynchronous operation is notified once this listener
 * is added by calling {@link Future#addListener(GenericFutureListener)}.
 */
public interface GenericFutureListener<F extends Future<?>> 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 Excep
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值