异步机制(Asynchronous) -- (一)开篇兼谈Mina

诚惶诚恐。我没有做过推荐,不知道为什么这篇就“被”推荐了。这只是一篇blog,肯定会有不当之处,请包涵,多指正。

 

之前写了篇blog 专门探讨异步/同步IO,但那只涉及了网络的IO。这段时间看了很多System方面的论文,且也在设计一个System,再加上最近刚用Mina实现了一个异步消息交互的模块。因此,将这段时间的心得记录下来,可能有些杂,希望能够有人喜欢看。

 

所谓同步,简单的说,A告诉B去做某件事情,然后就一直等待,直到B做完后返回给A,A才继续做其它的事情;
所谓异步,相反的,A告诉B做某件事情,然后就去干其它的事情了,B做完后再通知A。

无论是同步还是异步,其实都是指两个对象之间的交互。所以,判断什么是同步还是异步,首先要先明确指的是哪两个对象之间的关系。
举个例子:

[java]  view plain copy
  1. socket.write(request);  
  2. response = socket.read();  

这是一段常见的伪代码,用于Client向Server发送请求。在这里,可以说socket.write是一个同步IO,因为调用write操作以后,内核会将要写的数据放入到网卡的缓冲区中,然后再返回,所以,这里同步的两个对象分别是应用程序和内核;也可以说这段代码是一个同步消息机制,因为client将request发送给server后,一直等待直到server将response返回,这里同步的两个对象分别是client和server。

之前的那篇blog专门论述同步IO和异步IO,它指的是应用程序和操作系统内核间的关系。这里就不多谈了。这里谈谈Mina。Mina是一个非常流行的网络程序的框架,它提供的是异步的API(It provides an abstract • event-driven • asynchronous API)。
比如,如果client想要创建一个到server的连接,用mina可以这样写:

[java]  view plain copy
  1.  NioSocketConnector connector = new NioSocketConnector();  
  2. // 初始化connector...  
  3. //..........  
  4. connector.connect(address);  

看上去好像和一般的写法没什么两样。但是,这里的connector.connect()方法是一个异步的调用,意思是程序告诉mina要去连接address,mina返回说它会做这件事,但它可能还没有做完。所以,即便“connector.connect(address);”这行代码结束了,也并不意味着连接成功了(mina这时候可能还正在创建连接的过程中)。完整的写法应该是:

[java]  view plain copy
  1. ConnectFuture connFuture = connector.connect(address);  
  2. connFuture.addListener(new ConnectListener());  
  3.         private class ConnectListener implements IoFutureListener<ConnectFuture>{  
  4.               
  5.             public void operationComplete(ConnectFuture future) {  
  6.                   
  7.                 if (future.isConnected()) {  
  8.                     //get session  
  9.                     IoSession session = future.getSession();  
  10.                       
  11.                     session.write(...);  
  12.                       
  13.                 } else {  
  14.                       
  15.                     logger.error("can not create the connection .");  
  16.                 }  
  17.             }  
  18.         }  
  19.     }  
  20. }  

这里面最重要的一个类是ConnectListener,它实现了IoFutureListener<ConnectFuture>这个接口。这个类其实只有一个函数 – operationComplete,这是一个回调函数,它告诉mina一旦connect完成以后,就调用这个函数。我们这里的回调函数,首先判断一下连接是否成功,如果成功,那么就向这个链接中写入数据(session.write)。

回调函数在异步机制中扮演着非常重要的角色。 因为在同步机制中,调用者会等到结果返回然后自己执行接下来的操作,比如,上面这段代码如果写成同步的,大概是这个样子:

[java]  view plain copy
  1. boolean status = connector.connect(address);  
  2. if(status) {  
  3.     session.write(...);  
  4. else {  
  5.     logger.error("can not create the connection .");  
  6. }  

但是在异步机制中,就只能将connect后面的代码做成回调函数,注册到mina中。这样,当mina完成工作后它才知道接下去该干什么。

值得一提的是,虽然Mina号称是Asynchronous API,但它也提供了同步的方法。比如,上面这段代码,如果用Mina的同步机制是这样写的:

[java]  view plain copy
  1. ConnectFuture future = connector.connect(address);  
  2. future.awaitUninterruptibly();  
  3. IoSession session = future.getSession();  
  4.         // Send the first ping message  
  5.         session.write(....);  

重点在于“future.awaitUninterruptibly();”这行代码,它会将程序阻塞住,直到连接创建好,所以,当这行代码结束后,就可以直接获取session并执行write操作。

我在网上找到的大部分Mina示例代码都是基于同步的调用。所以,虽然很多人用mina,可是还是更习惯于同步的机制。至于为什么会这样,以后会再讨论。

 

未完待续~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值