最近大概看了ZooKeeper和Mina的源码发现都是用Java NIO实现的,因此有必要搞清楚什么是NIO。下面是我结合网络资料本身总结的,为了节约时间图示随便画的,能达意就行。编程
简介:服务器
BIO:同步阻塞式IO,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善。
NIO:同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有I/O请求时才启动一个线程进行处理。
AIO(NIO.2):异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
BIO
同步阻塞式IO,相信每个学习过操做系统网络编程或者任何语言的网络编程的人都很熟悉,在while循环中服务端会调用accept方法等待接收客户端的链接请求,一旦接收到一个链接请求,就能够创建通讯套接字在这个通讯套接字上进行读写操做,此时不能再接收其余客户端链接请求,只能等待同当前链接的客户端的操做执行完成。
若是BIO要可以同时处理多个客户端请求,就必须使用多线程,即每次accept阻塞等待来自客户端请求,一旦受到链接请求就创建通讯套接字同时开启一个新的线程来处理这个套接字的数据读写请求,而后马上又继续accept等待其余客户端链接请求,即为每个客户端链接请求都建立一个线程来单独处理,大概原理图就像这样:
虽然此时服务器具有了高并发能力,即可以同时处理多个客户端请求了,可是却带来了一个问题,随着开启的线程数目增多,将会消耗过多的内存资源,致使服务器变慢甚至崩溃,NIO能够必定程度解决这个问题。网络
NIO
同步非阻塞式IO,关键是采用了事件驱动的思想来实现了一个多路转换器。
NIO与BIO最大的区别就是只须要开启一个线程就能够处理来自多个客户端的IO事件,这是怎么作到的呢?
就是多路复用器,能够监听来自多个客户端的IO事件:
A. 若服务端监听到客户端链接请求,便为其创建通讯套接字(java中就是通道),而后返回继续监听,若同时有多个客户端链接请求到来也能够所有收到,依次为它们都创建通讯套接字。
B. 若服务端监听到来自已经建立了通讯套接字的客户端发送来的数据,就会调用对应接口处理接收到的数据,若同时有多个客户端发来数据也能够依次进行处理。
C. 监听多个客户端的链接请求和接收数据请求同时还能监听本身时候有数据要发送。
总之就是在一个线程中就能够调用多路复用接口(java中是select)阻塞同时监听来自多个客户端的IO请求,一旦有收到IO请求就调用对应函数处理。
各自应用场景
到这里你也许已经发现,一旦有请求到来(无论是几个同时到仍是只有一个到),都会调用对应IO处理函数处理,因此:多线程
(1)NIO适合处理链接数目特别多,可是链接比较短(轻操做)的场景,Jetty,Mina,ZooKeeper等都是基于java nio实现。并发
(2)BIO方式适用于链接数目比较小且固定的场景,这种方式对服务器资源要求比较高,并发局限于应用中。异步
附录:下面附上一个别人写的java NIO的例子。
服务端:
客户端:
http://blog.csdn.net/jiyiqinlovexx/article/details/42619097