Netty 学习 - 异步操作中的Future和Promise

原创 2016年12月25日 16:06:32


   本文继续介绍Netty的相关知识,主要讲解异步操作中的Future和Promise


由于Netty中的Future都是异步IO操作,结果是未知的,因此命名为ChannelFuture,表示跟Channel的操作有关


ChannelFuture提供了一系列不同于JDK Future的API,用于获取操作结果,添加事件监听器,取消IO操作,同步等待。


Netty强烈建议直接通过添加监听器的方式获取IO结果,而不是通过同步等待的方式
 
如果用户操作调用了sync或者await方法,会在对应的future对象上阻塞用户线程,例如future.channel().closeFuture().sync()


而最终触发future对象的notify动作都是通过eventLoop线程轮询任务完成的,例如对关闭的sync,因为不论是用户直接关闭或者eventLoop的轮询状态关闭,都会在eventLoop的线程内完成notify动作,所以不要在IO线程内调用future对象的sync或者await方法,因为应用程序代码都是编写的channelHandler,而channelHandler是在eventLoop的线程内执行的,所以是不能在channelHandler中调用sync或者await方法的


对于Future而言,提供的API有get与get(timeout) 前者是一直阻塞的get方法,后者带了超时时间,具体实现方式是在Future上执行wait方法,将当前运行线程进行阻塞,达到阻塞效果,而后通过eventLoop线程对Future对象进行notifyAll,保证唤醒阻塞的线程


而Future只有获取查询的API,类似于JDK中的Future,为了扩展对异步结果的写操作,Netty提供了Promise,继承于Future,可以用于设置IO操作的结果,在AbstratChannel的代码中可以看到对相关的IO操作都会新建Promise作为具体IO函数的参数,这样就能异步立即返回Promise,当IO操作后续发生异常或者完成时,将会设置promise的结果,在设置结果的过程中,包括以下三步
1  设置result的值
2  notifyAll,唤醒在本Promise上等待的线程
3  回调listener


下面以最常见的关闭等待操作为例,在大部分的网上例子中都会有如下的代码:
            Channel channel = b.bind(8080).sync().channel();
            channel.closeFuture().sync();
那么下面的channel.closeFuture().sync()实际是如何工作


channel.closeFuture()不做任何操作,只是简单的返回channel对象中的closeFuture对象,对于每个Channel对象,都会有唯一的一个CloseFuture,用来表示关闭的Future,
所有执行channel.closeFuture().sync()就是执行的CloseFuturn的sync方法,从上面的解释可以知道,这步是会将当前线程阻塞在CloseFuture上


一般来说,编写以上代码的都是在Main线程中用来启动ServerBootStrap的,所以Main线程会被阻塞,保证服务端Channel的正常运行


那么什么时候Main线程会被唤醒继续执行呢


在channel中有close方法,当调用close方法后,会按照pipeline.close   -  tail.close   - head.close - unsafe.close -  abstractChannel.doClose0 
 
private void doClose0(ChannelPromise promise) {
            try {
                doClose();
                closeFuture.setClosed();
                safeSetSuccess(promise);
            } catch (Throwable t) {
                closeFuture.setClosed();
                safeSetFailure(promise, t);
            }
        }




其中doClose方法是抽象方法,用来真正关闭IO连接,例如javaChannel.close


第二步则是用来处理CloseFuture的关闭,setClosed会执行trySuccess,这样就会在CloseFuture对象上执行notifyAll以及回调listener等,唤醒Main线程


第三步则是用来处理用户Future,前面说过在AbstratChannel的代码中可以看到对相关的IO操作都会新建Promise作为具体IO函数的参数,例如对于channel.close方法,分别有参数的方法和没有参数的方法,没有参数的方法实际在底层会自动new一个promise用来异步的返回结果,也可以在应用程序中主动编写一个Promise用来处理应用逻辑


在Promise对象上执行
  @Override
    public boolean trySuccess(V result) {
        if (setSuccess0(result)) {
            notifyListeners();
            return true;
        }
        return false;
    }




其中setSuccess0中会有  checkNotifyWaiters();的步骤,唤醒在该Promise对象上等待的线程,再notifyListeners进行回调Listener,完成设置动作




 




 

VC++游戏开发中学习数据结构

数据结构比较枯燥,结合游戏(例如植物大战僵尸等)开发,了解数据结构(链表、二叉树、HASH表的)的使用,知其然知其所以然。
  • 2017年07月18日 14:56

Netty4之Future/Promise异步模型

java.util.concurrent.Future是Java提供的接口,表示异步执行的状态,Future的get方法会判断任务是否执行完成,如果完成就返回结果,否则阻塞线程,直到任务完成。 [...
  • kobejayandy
  • kobejayandy
  • 2015-08-19 11:43:25
  • 14943

Netty4学习笔记(8)-- Channel接口

Channel是Netty4最核心的接口之一,拥有将近40个方法和一个内部接口。本文将对Channel接口的众多方法做一个归类和总结,为进一步研究Channel实现做准备。...
  • SpiderDog
  • SpiderDog
  • 2014-01-07 15:17:05
  • 6361

Netty5源码分析(七) -- 异步执行Future和Promise

java.util.concurrent.Future是Java提供的接口,表示异步执行的状态,Future的get方法会判断任务是否执行完成,如果完成就返回结果,否则阻塞线程,直到任务完成。 //...
  • ITer_ZC
  • ITer_ZC
  • 2014-09-23 09:42:20
  • 6018

netty5笔记-线程模型1-Promise

冬天实在太冷了,习惯了广东的天气,突然换个地方还真有点不适应, 早就想写的学习笔记也一直拖到现在。下面进入正题,一起来学习下netty的线程池实现。 我们知道java本身实现了一套线程池,即我们常见的...
  • youaremoon
  • youaremoon
  • 2015-12-13 01:03:37
  • 4216

Netty--Future和Promise

    Future用于获取异步操作的结果,Netty的Future都是与异步I/O操作相关的,因此,命名为ChannelFuture,代表它与Channel操作相关。ChannelFuture有两种...
  • cq17780734684
  • cq17780734684
  • 2018-03-19 09:56:26
  • 13

Netty源码分析(六)—Future和Promis分析

Netty源码分析(六)—Future和Promis分析 Future用来在异步执行中获取提前执行的结果 个人主页:tuzhenyu’s page 原文地址:Netty源码分析...
  • u013967175
  • u013967175
  • 2017-11-24 19:42:13
  • 177

netty5.0之Future和Promise

1、Future功能 Future最早来源于JDK的java.util.concurent.Future,它用于代表异步操作的结果。相关API如下: 可以通过get方法获取操作结果,如果操作尚未完成,...
  • lzlchangqi
  • lzlchangqi
  • 2014-12-19 18:41:53
  • 2147

Netty学习(三)-Netty重要接口讲解

上一节我们写了一个HelloWorld,对于Netty的运行有了一定的了解,知道Netty是如何启动客户端和服务器端。这一节我们简要的讲解一下几个重要的接口,初步探讨Netty的运行机制,当然刚学Ne...
  • a953713428
  • a953713428
  • 2017-03-26 18:10:10
  • 2983

Netty4详解二(开发第一个Netty应用程序)

原文地址:http://blog.csdn.net/suifeng3051/article/details/25238243     既然是入门,那我们就在这里写一个简单的Demo,客户端发送一个...
  • tanga842428
  • tanga842428
  • 2016-10-23 09:59:55
  • 5704
收藏助手
不良信息举报
您举报文章:Netty 学习 - 异步操作中的Future和Promise
举报原因:
原因补充:

(最多只允许输入30个字)