通俗而不失专业的介绍JAVA NIO N在哪里

本文主要目的是帮助大家更好的理解为什么NIO是N的而不是B的,不足之处欢迎来喷呦。

BIO  哪里B了

    大家都知道BIO是Blocking IO的意思,如果你引用了java.io包下面的某个类去帮助你做不管是网络IO还是文件IO的操作,那么恭喜你,你的代码很B。你可能不服,我哪里B了,凭什么说我B???别急,follow me 

    以网络IO为例,大家通常会习惯用一些第三方框架,比方说 apache的HttpClient,可能在代码层次不大能触碰到B(BIO)的感觉,但其实这些框架底层实现都是基于Socket,有过Socket编程(java环境)经验的同学对下面这种写法应该不会陌生:

                socket.getOuputStream();

                socket.getInputStream();

这其实就是BIO B的源头。这里以大家常写的客户端代码为例,Socket连接建立以后,通过socket.getInputStream写请求的内容,此处socket会阻塞,写完之后socket.outPutStream取服务端返回的内容,此处也会阻塞,其实outPutStream会阻塞比想象中更久的时间,只要该方法开始调用,socket就会被阻塞,即使当前outPutStream中还没有接收到从服务器端返回的数据,所以这种BIO的socket是从连接建立到数据接收完这一整个过程全程阻塞。

NIO  咋就不B了呢

     对java  NIO来说,原有的input/outputstream被 Channel取代,Channel全双工,读写都能做   其实linux底层还是socket,相对于bio而言,nio只是更好的利用了linux操作系统 Channel全双工的特性       

上面只是扯一扯,其实channel并不是nio非阻塞的关键(不关键你BB这么多)


NIO中原有的socket被SocketChannel代替,客户端要发送的数据写入ByteBuffer(Buffer有很多种,这只是比较常用的一个),通过Socket发出去,此时这个Socket不会阻塞在这里等着服务器端的响应,对java程序来说此时完全可以去做其他事情,不必像BIO一样阻塞在这里等着outPutStream里面有结果返回,此处即体现了NIO非阻塞的特点,那什么时候去拿服务器端返回的结果呢?这时候java NIO另一个特性就起作用了,Selector,我们可以起一个线程去轮询Selector(也可以不起线程,就地轮询,起了就是异步,不起就是同步),而Selector提供了几种方法去返回当前已经就绪的SocketChannel列表,底层利用了linux操作系统epoll的特性(暂时不考虑windows),epoll会以时间复杂度O(1)返回当前已经就绪即服务器端已经返回结果的SocketChannel列表。

再回到java  NIO,得到当前就绪的SocketChannel列表后,就可以从各个有结果的Channel里读数据到BufferByte,如果是同步调用,这时候直接处理返回结果即可; 如果是异步调用,可以通过调用用户提供的回调函数的方式去处理返回结果。此处如果用户定义了回调函数,即是异步调用    如果用户线程等待NIO的返回结果,即无需定义回调函数,此时即为同步调用        因为是NIO     二者都是非阻塞调用    只是同步异步的区别而已。

     以上就是为啥NIO不B的原因,其实只是大致说了一下过程,方便大家理解,想真正的了解掌握NIO这点东西肯定是不够的,me只是抛砖引玉,献丑一发。

Selector的几个方法:

public abstract Set<SelectionKey> keys();
// 获取当前就绪的SocketChannel列表 SelectionKey.channel
public abstract Set<SelectionKey> selectedKeys();
// 非阻塞  获取当前是否有Channel就绪的状态标志
public abstract int selectNow() throws IOException;
// 阻塞    带超时控制的 阻塞获取当前是否有Channel就绪的状态标志
public abstract int select(long var1) throws IOException;
// 阻塞    直至当前有Channel就绪
public abstract int select() throws IOException;

不想用B了,想用NIO怎么办

    上面说的都是原理性的东西,如果只是要会用NIO其实没必要完全搞懂原理(想成为大神还是去搞吧),推荐大家一个网络的NIO框架,也是apache出的,asynchttpclient,感兴趣的可以找一些相关资料用一用,还是很简单的。


结语

    学海无涯苦做舟,今天的学习就到这里,有问题留言,想喷一喷的也come on。想玩LOL开黑的就不要找我了,我要学习,不能分心(pentaKill)。








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值