Netty学习(五)-- Future & Promise

Future & Promise

在异步处理时,常用到这两个接口

首先要说明 Netty 中的 Future 与 JDK 中的 Future 同名,但是是两个接口,Netty 的 Future 继承自 JDK 的 Future,而 Promise 又对 Netty Future 进行了扩展。

  • JDK Future 只能同步等待任务结束(或成功、或失败)才能得到结果。
  • Netty Future 可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束。
  • Netty Promise 不仅有 Netty Future 的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器
功能/名称 JDK Future Netty Future Netty Promise
cancel 取消任务 - -
isCancelled 任务是否取消 - -
isDone 任务是否完成,不能区分任务成功或失败 - -
get 获取任务结果,阻塞等待 - -
getNow - 获取任务结果,非阻塞,还未产生结果时返回 null -
await - 等待任务结束,如果任务失败,不会抛异常,而是通过 isSuccess 判断 -
sync - 等待任务结束,如果任务失败,抛出异常 -
isSuccess - 判断任务是否成功 -
cause - 获取失败信息,非阻塞,如果没有失败,返回 null -
addListener - 添加回调,异步接收结果 -
setSuccess - - 设置成功结果
setFailure - - 设置失败结果
1)JDK Future

Future 好比一个容器,比如(一个线程)想让你的朋友(另一个线程)带点学习资料给你,朋友说你有没有U盘(Future 对象),我给装过来。你的朋友学习资料(return 结果)转到了U盘里,第二天拿给你。你就可以从U盘中拿到学习资料了。Future 是被动的,是由执行任务的那个线程往里面填结果。

/**
 * @desc
 * @auth llp
 * @date 2022/8/5 10:51
 */
@Slf4j
public class TestJskFuture {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1、线程池
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                2,
                2,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        // 2、提交任务
        Future<Integer> future = poolExecutor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.debug("执行计算...");
                TimeUnit.SECONDS.sleep(1);
                return 50;
            }
        });
        // 3、主线程通过 Future 来获取结果
        log.debug("等待结果...");
        log.debug("结果是 {}", future.get());
    }
}
2)Netty Future
/**
 * @desc
 * @auth llp
 * @date 2022/8/5 11:31
 */
@Slf4j
public class TestNettyFuture {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        EventLoop eventLoop = group.next();
        Future<Integer> future = eventLoop.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.debug("执行计算...");
                TimeUnit.SECONDS.sleep(1);
                return 50;
            }
        });
        log.debug("等待结果...");
        // 同步方式
        // log.debug("结果是:{}", future.get());
        // 异步方式
        future.addListener(future1 -> log.debug("结果是:{}", future1.getNow()));
    }
}
3)Netty Promise

通过以上两个例子 Future 都是由提交任务时返回创建的,被动的拿到 Future。不能够主动的创建。

/**
 * @desc
 * @auth llp
 * @date 2022/8/5 11:40
 */
@Slf4j
public class TestNettyPromise {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1、准备 EventLoop 对象
        EventLoop eventLoop = new NioEventLoopGroup().next();
        // 2、可以主动创建 Promise 创建
        DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);

        new Thread(()->{
            // 3、任意一个线程执行计算,计算完成之后向 promise 填充结果
            log.debug("开始计算...");
            try {
                TimeUnit.SECONDS.sleep(1);
                int i = 1 / 0;  // 计算出现异常
                promise.setSuccess(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
                promise.setFailure(e);
            }
        }).start();

        // 4、接收结果的线程
        log.debug("等待结果...");
        log.debug("结果是:{}", promise.get());
        // 异步
        // promise.addListener(future -> log.debug("结果是:{}", future.get()));
    }
}

你可能感兴趣的:(Netty,java,netty)