• 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利用率,让更少的线程做更多的事。
     
  • 相关阅读:
    Unity3D 4.0 界面 基础 入门
    try catch finally 用法
    Mysql表引擎Innodb、MyIsam、Memory
    初步的kudu+impala vs dorisdb vs tidb
    mysql创建类似oracle的dblink
    jedis请求keys超时报错
    php 1223
    php 1214
    php 1216
    php 1222
  • 原文地址:https://www.cnblogs.com/tspeking/p/9329243.html
Copyright © 2020-2023  润新知