NIO
提到这个词,很多人会条件反射的说出这样的话:
“非阻塞IO,速度快!”。
但是为什么非阻塞IO,就会比阻塞式IO速度快呢?
下面用一个普遍的例子形容一下阻塞io与非阻塞io的工作方式
有一个读取数据的任务A。
阻塞io工作方式:
1、尝试读取数据
2、如果数据没有准备完成(在web等工作环境下,经常出现此情况),重复步骤1
3、直到读取数据完成后,返回。
非阻塞io工作方式:
1、尝试读取数据
2、如果数据没有准备完成,返回失败。如果数据准备完毕,读取后返回。
根据两种工作方式,稍加思考大家都会明白他们的优劣,而不是简单的说出那句条件反射的话。。。
下面分析一下:
阻塞io的工作方式简单明了,符合常理,非常容易理解和应用。
带来的缺点就是等待时间不确定,当然可以通过限制超时时间来控制最长等待时间。
我们平时系统的大多数实现都是采用此工作方式,比如http请求、数据库操作等。
非阻塞io的工作方式,也很简单,但是应用起来可能就稍微复杂。
比如我们想要处理一个web请求。
最开始时socket处于ACCEPT状态(此时我们开始相应此请求)
然后我们试图读取web请求的内容(此时socket处于READ状态,read状态是一个持续的io过程)
如果socket中数据并未准备好(即内容并没有从网络上接受完毕),会直接返回读取失败
这时。。我们似乎就傻了,怎么办?没有数据就直接返回了。。。汗一个!
冷静过后,我们如果还想继续这份工作的话,就不能继续流汗,必须做点什么来搞定这次任务
最简单的方法就是在while(true){}中无线循环的来调用上述流程。
非阻塞io在实际运用时,不可能我们写一个简单的无限循环去等待一个io。
下面说一下java的nio包里的Selector的运作方式:
Selector就是一个socket选择器,
它不停地查看所有与他绑定的socket是否准备完成,哪一个io准备完成,它就会处理对应的channel
上面关于Selector的解释只是最通俗简单的说法。
MINA
提到这个词,也都会说:
“mina用了nio,速度快!”
其实套用以上理论,我就可以知道,非阻塞IO本身并不会比阻塞式IO快,只是因为在高并发访问时,
非阻塞IO能够一定程度上减少服务器瞬间的并发线程数,从而提高CPU执行效率。
基于以上分析,我们为什么需要多线程:
多线程本身并不能提高效率,因为他反而会在一定程度上降低CPU运算效率(特别是在线程数远远大于CPU核心数时),
多线程的好处在于异步,避免一个线程在等待其他资源时,cpu空闲
非阻塞IO本身也不会提高速度,只是他在一定程度上能够降低并发数,从而提高CPU效率
以上只是我作为一个菜鸟,根据自己的理解,说了一下非阻塞IO和阻塞式IO、NIO和传统IO的区别,和我对多线程的理解。
如果有错误,劳烦各位能够给予指正和批评。