Netty入门——Future和Promise接口

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty入门——Future和Promise接口相关的知识,希望对你有一定的参考价值。

目录

一、Future & Promise的概述

1.1、Future & Promise的说明

netty 中的 Future 与 jdk 中的 Future 同名,但是是两个接口,netty 的 Future 继承自 jdk 的 Future,而 Promise 又对 netty Future 进行了扩展

  • jdk Future 只能同步等待任务结束(或成功、或失败)才能得到结果
  • netty Future 可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束
  • netty Promise 不仅有 netty Future 的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器

1.2、Future & Promise的说明列表

功能/名称jdk Futurenetty FuturePromise
功能/名称jdk Futurenetty FuturePromise
cancel取消任务--
isCanceled任务是否取消--
isDone任务是否完成,不能区分成功失败--
get获取任务结果,阻塞等待--
getNow-获取任务结果,非阻塞,还未产生结果时返回 null-
await-等待任务结束,如果任务失败,不会抛异常,而是通过 isSuccess 判断-
sync-等待任务结束,如果任务失败,抛出异常-
isSuccess-判断任务是否成功-
cause-获取失败信息,非阻塞,如果没有失败,返回null-
addLinstener-添加回调,异步接收结果-
setSuccess--设置成功结果
setFailure--设置失败结果

二、jdk 的 Future代码示例

  • 示例代码

    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.*;
    /**
     * @description: jdk 的 Future示例
     * @author: xz
     */
    @Slf4j
    public class JdkFutureTest 
        public static void main(String[] args) throws ExecutionException, InterruptedException 
            // 1. 线程池
            ExecutorService service = Executors.newFixedThreadPool(2);
            // 2. 提交任务
            Future<Integer> future = service.submit(new Callable<Integer>() 
                @Override
                public Integer call() throws Exception 
                    log.debug("执行计算");
                    Thread.sleep(1000);
                    return 50;
                
            );
            // 3. 主线程通过 future 来获取结果
            log.debug("等待结果");
            log.debug("结果是 ", future.get());
        
    
    
  • 输出结果

三、netty 的 Future代码示例

3.1、同步接收结果代码示例

  • 示例代码

    import io.netty.channel.EventLoop;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.util.concurrent.Future;
    import io.netty.util.concurrent.GenericFutureListener;
    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    
    /**
     * @description: netty 的 Future示例
     * @author: xz
     */
    @Slf4j
    public class NettyFutureTest 
        public static void main(String[] args) throws ExecutionException, InterruptedException 
            getResult1();
        
        /**
         * 同步接收结果
         * */
        public static void getResult1() throws InterruptedException, ExecutionException 
            // 1. 准备 EventLoop 对象
            NioEventLoopGroup group = new NioEventLoopGroup();
            EventLoop eventLoop = group.next();
            // 2. 提交任务
            Future<Integer> future = eventLoop.submit(new Callable<Integer>() 
                @Override
                public Integer call() throws Exception 
                    log.debug("执行计算");
                    Thread.sleep(1000);
                    return 70;
                
            );
            // 3. 同步接收结果(即主线程通过 future 来获取结果)
            log.debug("等待结果");
            log.debug("结果是 ", future.get());
        
    
    
  • 输出结果

3.2、异步接收结果代码示例

  • 示例代码

    import io.netty.channel.EventLoop;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.util.concurrent.Future;
    import io.netty.util.concurrent.GenericFutureListener;
    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    
    /**
     * @description: netty 的 Future示例
     * @author: xz
     */
    @Slf4j
    public class NettyFutureTest 
        public static void main(String[] args) throws ExecutionException, InterruptedException 
            getResult2();
        
        /**
         * 异步接收结果
         * */
        public static void getResult2() throws InterruptedException 
            // 1. 准备 EventLoop 对象
            NioEventLoopGroup group = new NioEventLoopGroup();
            EventLoop eventLoop = group.next();
            // 2. 提交任务
            Future<Integer> future = eventLoop.submit(new Callable<Integer>() 
                @Override
                public Integer call() throws Exception 
                    log.debug("执行计算");
                    Thread.sleep(1000);
                    return 70;
                
            );
    
            //3. 异步接收结果
            future.addListener(new GenericFutureListener<Future<? super Integer>>()
                @Override
                public void operationComplete(Future<? super Integer> future) throws Exception 
                    log.debug("接收结果:", future.getNow());
                
            );
        
    
    
  • 输出结果

四、netty 的 Promise代码示例

4.1、获取成功结果代码示例

  • 示例代码

    import io.netty.channel.EventLoop;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.util.concurrent.DefaultPromise;
    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.ExecutionException;
    
    /**
     * @description: netty的Promise示例
     * @author: xz
     */
    @Slf4j
    public class NettyPromiseTest 
        public static void main(String[] args) throws ExecutionException, InterruptedException 
            getSuccessResult();
        
        /**
         *获取成功结果
         * */
        public static void getSuccessResult() throws InterruptedException, ExecutionException 
            // 1. 准备 EventLoop 对象
            EventLoop eventLoop = new NioEventLoopGroup().next();
            // 2. 可以主动创建 promise, 结果容器
            DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
            new Thread(() -> 
                // 3. 任意一个线程执行计算,计算完毕后向 promise 填充结果
                log.debug("开始计算...");
                try 
                    Thread.sleep(1000);
                    promise.setSuccess(80);
                 catch (Exception e) 
                    e.printStackTrace();
                    promise.setFailure(e);
                
    
            ).start();
            // 4. 接收结果的线程
            log.debug("等待结果...");
            log.debug("结果是: ", promise.get());
        
    
    
  • 输出结果

4.2、获取异常结果代码示例

  • 示例代码

    import io.netty.channel.EventLoop;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.util.concurrent.DefaultPromise;
    import lombok.extern.slf4j.Slf4j;
    import java.util.concurrent.ExecutionException;
    
    /**
     * @description: netty的Promise示例
     * @author: xz
     */
    @Slf4j
    public class NettyPromiseTest 
        public static void main(String[] args) throws ExecutionException, InterruptedException 
            getExceptionResult();
        
        /**
         *获取异常结果
         * */
        public static void getExceptionResult() throws InterruptedException, ExecutionException 
            // 1. 准备 EventLoop 对象
            EventLoop eventLoop = new NioEventLoopGroup().next();
            // 2. 可以主动创建 promise, 结果容器
            DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
            new Thread(() -> 
                // 3. 任意一个线程执行计算,计算完毕后向 promise 填充结果
                log.debug("开始计算...");
                try 
                    int i = 1 / 0;
                    Thread.sleep(1000);
                    promise.setSuccess(80);
                 catch (Exception e) 
                    e.printStackTrace();
                    promise.setFailure(e);
                
    
            ).start();
            // 4. 接收结果的线程
            log.debug("等待结果...");
            log.debug("结果是: ", promise.get());
        
    
    
  • 输出结果

以上是关于Netty入门——Future和Promise接口的主要内容,如果未能解决你的问题,请参考以下文章

[netty4][netty-common]Future与Promise分析

7. Netty源码分析之Future和Promise

Netty中的Future与Promise

Future和Promise的分析

netty的Future异步回调难理解?手写个带回调异步框架就懂了附源码

95-24-020-Future-Future简介