最近在学习NIO的知识,故整理一下相关知识,并使用网络IO的案例做以说明
BIO
- 概念:同步阻塞IO,就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。
以上模型会有以下问题
- 服务器会为每个客户端请求建立一个Thread,由该线程单独负责处理一个客户请求。这种模式带来的一个问题就是线程数量的剧增,大量的线程会增大服务器的开销。大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大数量,这由带来了新的问题,如果线程池中有200个线程,而有200个用户都在进行大文件下载,会导致第201个用户的请求无法及时处理,即便第201个用户只想请求一个几KB大小的页面。
2 . 上述模型的另一个问题是,一个线程把一次交互的事情全部做了,包括读取,解码,计算,编码,响应,以及连接,线程的粒度太大
NIO
- 概念:同步非阻塞IO, Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。
- NIO 是利用了创建一个单线程,轮询事件的机制,通过高效地定位就绪的 Channel,来决定做什么,仅仅 select 阶段是阻塞的,可以有效避免大量客户端连接时,频繁线程切换带来的问题,应用的扩展能力有了非常大的提高。
- 面向缓存,数据的写入和读取增加Buffer缓冲区,将数据的读取和写入解耦,达到非阻塞的特点
这种NIO的实现方式有select,poll,epoll等不同方式
Seletor模型:
- 缺点:监听注册事件由数组管理, 数组是有长度的, 32位机上限1024, 64位机上限2048。轮询查找时需要遍历数组
poll模型:
- 把select的数组采用链表实现,因此没了最大数量的限制
epoll模型:
- 它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了
参考资料(http://www.sohu.com/a/119086870_505779)
https://www.cnblogs.com/ivaneye/p/5731432.html
网友评论