zoukankan      html  css  js  c++  java
  • Java的中BIO、NIO、AIO-1

    Java的中BIO、NIO、AIO-1

    最近在项目中用到TCP通信来完成命令和运行结果的交互,用的是典型的TCP通信中的C/S架构,原因很简单:在业务需求低的环境下,这种架构简单、稳定还容易写。但是在实际部署的情况下,一直出现读不到数据的空指针异常,按说BIO模式开发的应该阻塞直到有数据读取,没有找到原因就变通写了一个消息队列,使用定时器每1s从定时器中拿数据,解决了这个问题。但是想想这种同步阻塞的形式,就想了解一下其他的模式:NIO、AIO。好了,啰嗦了好多,进入正题:

    IO操作的基本概念

    在说明BIO/NIO/AIO之前,要先弄明白这些概念和原理,什么是同步、异步,阻塞和非阻塞:

    • 同步
      在IO操作中,同步指的是用户进程出发IO操作并等待或者轮询的去查看IO操作是否就绪
    • 异步
      异步是指用户进程在出发IO操作之后,便开始做自己的事情,IO操作由系统来完成,而当IO操作完成的时候,用户进程会得到系统IO已经完成的通知。
    • 阻塞
      阻塞是指进程在访问数据(读写操作)的时候,如果得不到数据就一直等待直到数据就绪,进行下一步的操作。
    • 非阻塞
      非阻塞是指进程在访问数据(读写操作)的时候,进程会立即得到一个返回值,而不是一直等待下去。

    总结起来同步异步是针对应用程序和内核的交互而言的,而阻塞和非阻塞是针对进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,就是一种读取和写入操作实现方式。更底层一点来说,同步和异步只是跟IO操作过程中进程的状态变化有关,而阻塞和非阻塞就是进程的两种状态。不要混淆了这些东西。

    根据上面的基本概念,生成常见的四种IO模式:

    • 同步阻塞IO
    • 同步非阻塞IO
    • 异步阻塞IO
    • 异步非阻塞IO

    下面来一一的说明这四种模型:

    • 同步阻塞IO
      同步阻塞IO是最简单的IO模型,在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!

    同步阻塞IO

    同步阻塞IO

    • 同步非阻塞IO
      在此种方式下,用户进程发起一个IO操作以后,就可以返回做其他的事情,但是用户进程需要时不时的去询问IO操作是否就绪,这就需要用户进程不断的去轮询、重复请求,这样会消耗大量的cpu资源。一般情况下很少使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

    同步非阻塞

    同步非阻塞

    • 异步阻塞IO
      这种模式是指一个应用发起一个IO操作之后,不等待内核IO操作的完成,等IO操作真正完成的时候,应用程序会得到IO操作完成的通知。这其实就是同步和异步的最关键区别,同步必须等待或者主动的去询问IO操作是否完成,那为什么说是阻塞呢?因为此时是通过select系统调用完成的,而select函数本身的实现方式是阻塞的,采用select函数有两个好处就是它可以同时监听多个文件句柄,从而提升系统的并发性。

    nio

    nio

    从上图中可以看到,用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回。当数据到达时,socket被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行。使用select函数的优点并不仅限于此。虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率。

    • 异步非阻塞IO
      此种模式,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的处理完成之后,应用程序会得到IO操作完成的通知,此时用户只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读写操作已经由内核完成了。在IO多路复用模型中,事件循环将文件句柄的状态事件通知给用户线程,由用户线程自行读取数据、处理数据。而在异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程指定的缓冲区内,内核在IO完成后通知用户线程直接使用即可。

    aio

    aio

    上面简单的介绍了一下目前服务器编程中常见的几种IO模型,但是真正把这几种IO模型付诸实施的是几种设计模式:

    • C/S模式,这是经典的BIO通信模型。
    • Reactor模式 是异步阻塞IO的处理模型
    • Proactor模式 是异步非阻塞IO的处理模型

    第二篇说明详细的说明这几种模式!!

  • 相关阅读:
    241. Different Ways to Add Parentheses java solutions
    89. Gray Code java solutions
    367. Valid Perfect Square java solutions
    46. Permutations java solutions
    116. Populating Next Right Pointers in Each Node java solutions
    153. Find Minimum in Rotated Sorted Array java solutions
    判断两颗树是否相同
    求二叉树叶子节点的个数
    求二叉树第k层的结点个数
    将二叉排序树转换成排序的双向链表
  • 原文地址:https://www.cnblogs.com/chailinbo/p/9226277.html
Copyright © 2011-2022 走看看