Netty异步模式基本介绍

前言

Netty是一个异步的、基于事件驱动的网络应用程序框架,本文主要介绍Netty的异步机制。

注:关于Netty基础,可以查看 Netty基本介绍 和 线程模型 Netty基本介绍 和 线程模型 这篇文章,本文代码也是基于这篇博文中代码修改的。

一、 同步异步 & 阻塞非阻塞 的区别

1. 关于同步和异步

  • 同步:

    当发起io资源请求,在io资源尚未就绪时,调用者会主动获取io资源的状态,当资源就绪时,调用者主动获取当前资源就绪的状态,就会返回结果。

  • 异步:

    当发起io资源请求,在io资源尚未就绪时,调用者会立刻获得返回结果。 当资源就绪时,被调用者主动通过状态、通知来告知调用者,或者通过回调方式告知。

    一个常用的例子是

  • 同步:

    你想喝开水,在炉灶上烧水(发起io请求),水壶经过一段时间的加热(io资源未就绪),你发现水烧开了,将水壶取下(返回结果)

  • 异步:

    你想喝开水,你有一个高级水壶,在炉灶上烧水(发起io请求),水壶配套一个水开警报器,你拿走警报器然后去干别的事,经过一段时间的加热(io资源未就绪),水烧开了,水壶通过警报器给你通知(返回结果)

2. 关于阻塞和非阻塞

  • 阻塞:

    阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

  • 非阻塞:

    非阻塞调用指在不能立刻得到结果之前,调用者还可以去干别的事情,不会一直等待当前结果的返回。

    举例

  • 阻塞:

    你想喝开水,在炉灶上烧水(发起io请求),水壶经过一段时间的加热(io资源未就绪),此时你需要一直等待水壶烧开

  • 非阻塞:

    你想喝开水,在炉灶上烧水(发起io请求),水壶经过一段时间的加热(io资源未就绪),此时你不需要一直等待水壶烧开,可以去做别的事情

3. 总结

​ 结合下面流程图理解,调用者从发起资源请求 到 获取结果。

请添加图片描述

  • 同步异步 关注的是 资源准备就绪后,调用者是如何获知的
  • 阻塞非阻塞 关注的是 资源准备过程中,调用者是否能做别的事
  • 注:同步非阻塞的做法是 资源准备过程中,调用者可以去做别的事,但需要经常回来看看资源是否就绪,当发现资源就绪时,获取结果。

二、 Netty的异步机制

  • Netty 中的 I/O 操作是异步的(Bind、Connect、Write等操作 ),会立刻返回一个 ChannelFuture。

  • 调用者并不能立刻获得结果,而是通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得IO 操作结果。

  • Netty 的异步模型是建立在 future 和 callback 的之上的。 callback 就是回调。重点说 Future,它的核心思想是:假设一个方法 fun,计算过程可能非常耗时,等 待 fun 返回显然不合适。那么可以在调用 fun 的时候,立马返回一个 Future,后续可以通过 Future 去 监控方法 fun 的处理过程(即 : Future-Listener 机制)

  • Netty中的future

    • future是netty异步操作立刻返回的结果, 可以通过它提供的方法来检测执行是否完成,ChannelFuture 是他的一 个子接口。ChannelFuture 是一个接口 ,可以添加监听器,当监听的事件发生时,就会通知到监听器 。

    • 当 Future 对象刚刚创建时,处于非完成状态,调用者可以通过返回的 ChannelFuture 来获取 操作执行的状态, 注册监听函数来执行完成后的操作。

    • 常用方法:

      方法介绍
      sync 方法阻塞等待程序结果反回
      isDone 方法判断当前操作是否完成
      isSuccess 方法判断已完成的当前操作是否成功
      getCause 方法获取已完成的当前操作失败的原因
      isCancelled 方法判断已完成的当前操作是否被取消
      addListener 方法注册监听器,当操作已完成(isDone 方法返回完成),将会通知指定的监听 器;如果Future 对象已完成,则通知指定的监听器

三、 使用方法

给future添加监听器,监听操作结果

  • 修改Server端口绑定处的代码,添加Listener监听端口绑定的状态

            ChannelFuture channelFuture = serverBootstrap.bind(9988).sync();
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()){
                        System.out.println("Server bind success...");
                    }else {
                        System.out.println("Server bind failed!!!");
                    }
                }
            });
    
  • 修改Client发送数据的自定义Handler代码,添加Listener监听数据发送的状态

        //通道就绪
        @Override
        public void channelActive(ChannelHandlerContext channelHandlerContext) throws Exception{
            ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("hello,nettyServer...", CharsetUtil.UTF_8));
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()){
                        System.out.println("Client send success...");
                    }else {
                        System.out.println("Client send failed!!!");
                    }
                }
            });
        }
    
  • 测试结果:

    请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值