几句话讲清楚为什么NIO是同步非阻塞的

1、首先看一下NIO的模型,简单了解一下模型的结构。

事实上可以将这个模型理解为观察者模式,reactor将观察到的select事件通知给对应的订阅者。(select代表逻辑意义上的系统调用,事实上可能使用select或epoll、poll,它们的联系和区别不多做解释)

reactor模型

2、用一段伪代码来展示这个过程

//注册需要监听的连接
select.registerConnections(connections);
//通过系统调用轮询io连接,当有就绪事件时就会进入循环中
while(select()){
	//获取就绪事件列表
   List<Event> events = getEvents();
   //处理事件的逻辑
   for(Event event : events){
       Handler handler = getHandler(envent);
       handler.do();
   }
}

3、什么是同步和异步?什么是阻塞和非阻塞?

首先要知道,同步和异步是针对调用方,阻塞与非阻塞是针对被调用方的。

  • 同步与异步:对于调用方来讲调用一个方法是否需要等待调用方法的返回结果就是同步和异步的区别。如果需要等待函数的返回就是同步,不等待则是异步
  • 阻塞与非阻塞:对于被调用方来说,当被调用方调用时是否立即返回结果就是阻塞与非阻塞的区别。如果被调用方立即返回结果就是非阻塞的,反之如果需要等待处理过程结束后才返回结果就是阻塞的。

4、NIO为什么是同步非阻塞的?

  1. 观看下列伪代码,可以看到作为调用方一直在轮询select,每一次轮询都需要等待select调用的结果返回。不论select是否是阻塞的,同步都是成立的。
//通过系统调用轮询io连接,当有就绪事件时就会进入循环中
while(select()){
   // do something
}

那么如何才算是异步呢?观看下列伪代码,当然,NIO模型并没有这么做,AIO才这么做

//当有就绪事件时系统调用主动通知我去做事
select().register((event)->{
     // do something 
});
  1. 观看下列伪代码,可以看到 while()的条件是select()调用。 在select中注册了很多非阻塞的IO连接,select本质上是对注册的所有IO连接进行轮询(epoll是通知的方式,有事件了通知给epoll,不用全量遍历)查询事件,如果有就绪事件就返回给调用方,否则就将调用方阻塞在原地。可能有人觉得select阻塞了为什么还是非阻塞模型?其实select的不阻塞也是可以的,但是如果select不阻塞会引起CPU空转,这是资源的浪费,而且这个阻塞是针对所有连接都没有可处理的数据来讲的,其中的每一个连接是非阻塞的。
//建立非阻塞的连接 ,即无论数据有没有就绪,都会第一时间返回。
boolean wait = false;
Connector connector = new Connector(wait);
//将连接注册到select列表中
select.registConnector(connector);
//通过系统调用轮询io连接,当有就绪事件时就会进入循环中
while(select()){
   // do something
}

5、总结

可以看到Reactor模型是多对多的特殊的观察者模式又或者叫做发布订阅模式。对于负载很大的服务端程序来说,线程是稀缺资源,无节制的线程创建显然是不合理的,在Reactor这种模式下,NIO对线程的利用率几乎提高到了极致,但其中还有可优化的点,比如同步非阻塞中的最后一点同步是否还可以优化?当然可以,于是AIO(异步非阻塞IO模型)来了,但这不是我们今天要谈论的点。
另外,文章中的代码是为了更好的表达清楚NIO的思想编写的伪代码。

最后希望各位巨佬指正错误,也希望来试用指导一下我的软件,下载地址 ,地址中有部分开源代码的地址,希望可以得到一颗星星。

此致,敬礼!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

54号考生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值