项目作者: oldDong

项目描述 :
Unix中的5个IO模型和Java中的几种IO原理
高级语言: Java
项目地址: git://github.com/oldDong/io-demo.git
创建时间: 2019-01-25T03:50:48Z
项目社区:https://github.com/oldDong/io-demo

开源协议:

下载


基本概念

1、同步和异步

  1. 同步:
  2. A调用BB的处理是同步的,在处理完之前他不会通知A,只有处理完之后才会明确的通知A
  3. 异步:
  4. A调用BB的处理时异步的,B在接到请求后先告诉A我已经接到请求了,然后异步去处理,处理完之后通过回调等方式再通知A
  5. 总结:
  6. 同步和异步最大的区别是被调用方的执行方式和返回时机。同步指的是被调用方做完事情之后再返回,异步指的是调用方先返回,然后再做事情,做完之后再想办法通知调用方

2、阻塞和非阻塞

  1. 阻塞:
  2. A调用BA一直等着B的返回,别的事情什么都不干
  3. 非阻塞:
  4. A调用BA不用一直等着B的返回,先去忙别的事情。
  5. 总结:
  6. 阻塞和非阻塞最大的区别是在被调用方返回结果之前的这段时间内,调用方是否一直等待。阻塞指的是调用方一直等待别的事情什么都不做,非阻塞指的是调用方先去忙别的事情。

区别:

  1. 阻塞、非阻塞说的是调用者,同步、异步说的是被调用者。

Unix中的五种I/O模型

  1. 一次I/O访问(read为例),数据(本地、网络)---->操作系统内核的缓冲区---->应用程序的地址空间
  2. 两个阶段:
  3. 1、等待数据准备
  4. 2、将数据从内核拷贝到进程中

1、同步阻塞IO

  1. 阶段1:等待数据就绪。网络I/O的情况就是等待远端数据陆续抵达,也就是网络数据被复制到内核缓冲区;磁盘I/O的情况就是等待磁盘数据从磁盘上读取到内核态内存中。
  2. 阶段2:数据拷贝。出于系统安全,用户态的程序没有权限直接读取内核态内存,因此内核负责把内核态内存中的数据拷贝一份到用户态内存中

2、同步非阻塞IO

  1. 阶段1:用户进程可选择做其他事情,通过轮询的方式查看内核缓冲区是否就绪。如果数据就绪再去执行阶段2

3、多路复用I/O(select和poll)

  1. 指内核一旦发现进程指定的一个或者多个IO条件准备就绪,它就通知该进程。
  2. 与同步非阻塞IO不同的是,原来需要用户进程去轮询的这事儿交给了内核线程帮你完成

4、信号驱动I/O(SIGIO)

5、异步非阻塞I/O

  1. 用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。
  2. IO两个阶段,用户进程都是非阻塞的

Java流中的几种I/O

1、IO/BIO

  1. BIO就是指IO,即传统的Blocking IO, 即同步并阻塞的IO
  2. 依赖于ServerSocket实现,即一个请求对应一个线程,如果线程数不够连接则会等待空余线程或者拒绝连接

2、NIO

  1. Non-Blocking IO,即同步不阻塞的IO
  2. java.nio包下面,核心元素包括BufferChannelSelector
  3. 客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询连接,有I/O请求时才会启动一个线程进行处理。它的特点是要不断主动地去询问数据有没有处理完,一般适用于连接数目较大但连接时间较短的应用,如聊天应用。

3、AIO

  1. jdk1.7开始引入,即异步不阻塞的IO
  2. 先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间长的应用。
  3. AsynchronousFileChannel: 用于文件异步读写;
  4. AsynchronousSocketChannel: 客户端异步socket
  5. AsynchronousServerSocketChannel: 服务器异步socket

NIO到Netty

  1. JDK自带的NIO过于复杂,Netty是一个基于NIO的客户、服务端编程框架,Netty简化了网络应用的开发过程。