首页 新闻 会员 周边

关于NIO的一些疑问

0
悬赏园豆:100 [已解决问题] 解决于 2013-12-30 09:35

C#里貌似没有这个概念吧?最近在做android的时候看到的,然后去查了下资料,有一些疑问。

首先是网上说的

java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。

问题1:这里说,不必开多个线程死等,我有点无法理解。一般如果做普通IO通信,比方说Socket,那么我们会给每个Socket开启一个线程,这个线程的目的是让socket做Read()时不阻塞主线程对不对?那么NIO是否是不执行这个Read()操作,或者说,是让专门一个线程,定时对所有连接做一个Read()操作,然后马上关闭Read(),执行下一个?

问题2:假如上述成立,那就是说NIO其实还是保持着Socket之间的连接?比方说有三个Socket连接到服务器,那就是开启一个数组,定时轮询这三个socket的Read()?还是说,只是保持了这三个连接的地址,需要时再连接(这个感觉不太可能,因为是服务端主动连接客户端,这个疑问是我在使用Netty4时产生的)。

问题3:关于Buffer。其实在java和C#的文件读写中都有buffer,这是否说明两者的IO都已经封装成NIO了?另外关于Buffer的工作原理,NIO本质还是基于IO的吧?而IO得Read应该是一个字节一个字节读取的,那NIO是如何使其变成一个块一个块读取的呢?我的想法是:其实本质还是一个字节一个字节读取,不过是读取了指定个数的字节后,才让Reactor触发事件,不知道是否如此?

谢谢各位大牛解答问题。个人问问题喜欢先阐述自己的想法,望纠正。

NIO
林J的主页 林J | 菜鸟二级 | 园豆:202
提问于:2013-12-26 11:41
< >
分享
最佳答案
0

问题1,
传统阻塞式的连接方式是每个连接一个线程,当连接数较多的时候(如上千并发),线程的创建和切换所带来的开销就非常大了。
一种的解决方案就是无阻塞式的reactor模型(linux中的epoll):将所有连接放在一个线程中轮询,有读写事件的时候再执行相应的回调处理。这个主要是用在服务器端减少线程数的。 而对于客户端来说,如果socket连接不多的话,每个连接直接单独启动一个线程处理socket也是可行的。

问题2,socket连接自然是长期保存了,关闭了就没有IO事件了。
问题3,buffer和是否阻塞则没有关系。

至于.net,由于windows没有epoll之类的高效率同步api(select效率较低),它使用的是异步socket——iocp,这种方式一般称为proactor模型。具体可以参考这篇文章:http://www.ibm.com/developerworks/cn/java/j-lo-iocp/

收获园豆:55
天方 | 大侠五级 |园豆:5407 | 2013-12-29 19:16
其他回答(4)
0

我建议你了解下 select、poll、epool、 iocp,等你弄明白了再来重新整理你的问题。

收获园豆:30
Launcher | 园豆:45045 (高人七级) | 2013-12-26 11:52

看了下相关知识。传统的IO操作应该是TPC(Thread PerConnection)模型,而我所理解和阐述的应该属于Select模型。NIO应该就是EPOL模型了。那么说NIO其实是通过注册事件,等待事件触发的通知方式,那NIO种的Selector选择器究竟是在做什么操作呢?在我原来的理解中选择器是用来轮询每个连接的。

支持(0) 反对(0) 林J | 园豆:202 (菜鸟二级) | 2013-12-26 12:55

@Launcher: 这篇博文没多少对我有用的东西,倒是重新去看了下反应器模式,有了点收获。应该是事件通知到Selector,而不是Selector主动去轮询。不过这篇文章倒是讲到了在早期NIO中,使用的是select模型,JDK 6后才换成Epol模型。

支持(0) 反对(0) 林J | 园豆:202 (菜鸟二级) | 2013-12-26 13:20
0

跟C#不C#的没什么关系,是底层怎么实现无阻塞IO的问题

IO不单只网络流,还有其他,

之所以会有这个课题,是因为

一般我们要获取一个数据的时候,首先会想数据源发出一个请求.

数据源吧请求的数据返回给我们,在发出请求后,当前线程就是锁住IO,这样就造成了阻塞

无阻塞模式就是,当你对数据源发出请求后,并不等待数据源返回数据,不锁IO,

而是给这次请求注册一个响应函数,当IO返回数据时,再调用该回调函数.在请求和响应的过程中IO任然可以接受其他请求

这样来实现无阻塞IO

收获园豆:10
吴瑞祥 | 园豆:29449 (高人七级) | 2013-12-26 12:26
0

愚见:java的nio本质上是开了一个线程专门

轮询(如timer)在查询所有的socket的是否有数据来.

没有数据来,接着查询下一个.

------------------个人估计

收获园豆:5
迅捷网络[来送福利] | 园豆:578 (小虾三级) | 2013-12-26 16:42

简单来说,在windows平台上确实是这样,再多点限定,应该是轮询是否有注册的事件触发。不过reactor模式都是建立在操作系统的基础上实现的,不同的操作系统有不同的实现方式,在Linux系统上其实是使用事件回调进行触发的,效率要更高。查了一下午资料后得出的结论。

支持(0) 反对(0) 林J | 园豆:202 (菜鸟二级) | 2013-12-26 16:49
0

nio我硬是没看懂。

angelshelter | 园豆:9887 (大侠五级) | 2013-12-26 23:08
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册