zoukankan      html  css  js  c++  java
  • JAVA NIO原理剖析

    本文不打算讲解BIO怎么用?NIO如何用?本文重点是NIO底层原理。
    本文打算从以下几个方面讲解:
    1、BIO通讯模型(网络方面)是什么?
    2、NIO通讯模型(网络方面)是什么?解决了什么问题?
     
    1. BIO通讯模型
    模型解释:
    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利用率,让更少的线程做更多的事。
     
  • 相关阅读:
    WebApi 生成接口文档
    MVC POST 嵌套格式的数据到Controller
    使用ABP框架的项目找不到system.web.http的解决办法
    SQLServer使用XML拆分以逗号分隔的字符串
    webapi使用swagger出现“Cannot read property 'parameters' of null”
    部署到IIS后出现ORA-12560的解决办法
    【ORACLE】“System.Exception: System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本。”解决办法
    Go安装和简单配置开发环境
    怎么安装Jupyter Notebook主题皮肤并设置教程
    如何修改Anaconda中Jupyter Notebook默认工作路径(保存文件路径)
  • 原文地址:https://www.cnblogs.com/tspeking/p/9329243.html
Copyright © 2011-2022 走看看