• 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());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
    • 输出结果
      在这里插入图片描述

    三、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());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
    • 输出结果
      在这里插入图片描述

    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());
                  }
              });
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
    • 输出结果
      在这里插入图片描述

    四、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());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
    • 输出结果
      在这里插入图片描述

    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());
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
    • 输出结果
      在这里插入图片描述

  • 相关阅读:
    双通道音频功率放大电路,外接元件少, 通道分离性好,3V 的低压下可正常使用——D2025
    golang技术降本增效的手段
    【Shell】进程内存过高告警脚本
    虾皮店铺所有商品数据接口(shopee.item_search_shop)
    详解容灾恢复过程中跨数据中心级的关键故障切换
    如何制作网页链接自动录入工具
    Python基础教程:序列排序
    【SpringBoot篇】基于SpringBoot进行Web开发
    Spring框架(一):SpringBean的生命周期以及循环依赖和处理方式
    我和EarthSDK Cesium那点事(零)
  • 原文地址:https://blog.csdn.net/li1325169021/article/details/127666563