频道栏目
首页 > 资讯 > Java > 正文

JAVA NIO原理剖析及应用讲解

18-07-19        来源:[db:作者]  
收藏   我要投稿

模型解释:

BIO场景下,客户端(Client)发起连接请求,服务端接收到请求后,会分配一个业务线程处理这次访问,执行业务处理,写入响应流。

无论是服务端还是客户端,数据的读写都是阻塞的。比如,服务端收到客户端的请求,想要获取客户端传过来的请求参数,就会执行读操作,此时,如果由于网络原因导致客户端写入数据慢或者服务端接收数据慢,这个过程会非常耗时,此时应用线程就只能阻塞等待数据可读,这个过程会很浪费CPU资源的。并且,随着用户请求的增多,阻塞队列满了,而应用线程没有释放,就会导致后来的请求被抛弃,得不到处理。

为什么会出现这种情况?究其原因,服务端执行读数据的操作,本质上是CPU向操作系统内核发出一条指令,让操作系统通过TCP/IP协议,从网络读取数据到内核,再从内核到内存中。CPU执行指令速度非常快,而操作系统执行IO的速度远远赶不上CPU执行指令的速度,就会导致CPU时间的浪费。

2.NIO通讯模型

模型解释:

NIO场景下,客户端(Client)发起请求,服务端接收请求后,并不是直接分配业务线程处理这次请求,而是交给专门的IO线程(JAVA 中的Selector)读取请求流,当数据准备好以后,才会交给业务线程执行业务逻辑,最后交给IO线程写入响应流。

到这里,读者可能会有两个疑问?NIO模型下,IO线程会成为瓶颈?NIO解决了什么问题(与BIO相比)?

IO线程会成为瓶颈吗?这个问题得从IO线程的底层实现说起,NIO之所以是同步非阻塞,就是因为底层操作系统支持同步非阻塞,JVM只是通过系统调用本地方法实现同步非阻塞的(本质上是操作系统实现同步非阻塞,而JVM只是通过本地方法执行系统调用而已)。linux系统提供了epoll系统调用,epoll是基于事件驱动方式来实现的(也就是说,底层操作系统准备好了数据,以事件驱动的机制回调通知),而NIO中的Selector的select()方法调用,是通过本地方调用epoll系统调用来实现非阻塞的,最大限度利CPU时间片,所以IO线程的瓶颈也就是硬件瓶颈。

NIO解决了什么问题?

通过单独的IO线程,当有可读、可写的事件发生的时候再去做读写操作,这个时候就不用像BIO那样一直阻塞等待在那,业务线程就可以被释放出来做更多的事情。说白了,提高了CPU利用率,让更少的线程做更多的事。

相关TAG标签
上一篇:搭建KVM服务器教程
下一篇:JQuery函数加载顺序实例讲解
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站