Java IO 基本概念

介绍

  • IO 分类
  • 同步、异步、阻塞、非阻塞理解
  • BIO、NIO、AIO 介绍
  • Linux 5 种 IO 模型

IO 分类

  • 按传输数据方式:

字节流:以 byte 为基本单位进行,XXXStream 表示字节流

字符流:以字符为基本单位,字符又根据编码方式不同,一个字符对应不同大小的 byte。XXXReader、xxxWriter 表示字符流相关类

字节流可以处理任何类型的数据,如图片,视频等;字符流只能处理字符类型的数据。

  • 按输入输出方向:

输入流(InXXX)、输出流(OutXXX)

同步、异步

调用者是否主动等待调用的返回结果,

同步和异步关注的是消息通信机制,即消息是怎么返回的,是直接返回还是通过回调返回。

同步和异步的区别最大在于异步的话调用者不需要等待处理结果,被调用者会通过回调等机制来通知调用者其返回结果。

阻塞、非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起,不能执行其它业务。调用线程只有在得到结果之后才会返回。

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

你妈妈让你烧水,小时候你比较笨啊,在那里傻等着水开(同步阻塞)。等你稍微再长大一点,你知道每次烧水的空隙可以去干点其他事,然后只需要时不时来看看水开了没有(同步非阻塞)。后来,你们家用上了水开了会发出声音的壶,这样你就只需要听到响声后就知道水开了,在这期间你可以随便干自己的事情,你需要去倒水了(异步非阻塞)。

聊聊同步、异步、阻塞与非阻塞

IO 类

upload successful

BIO、NIO 和 AIO 的区别

  • BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的方式是同步、阻塞方式,也就是说在读入输入流或者输出流时,在读写动作完成之前,线程会一直阻塞在那里,它们之间的调用时可靠的线性顺序。它的有点就是代码比较简单、直观;缺点就是 IO 的效率和扩展性很低,容易成为应用性能瓶颈。

  • NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以构建多路复用的、同步非阻塞 IO 程序,同时提供了更接近操作系统底层高性能的数据操作方式。

  • AIO 是 Java 1.7 之后引入的包,是 NIO 的升级版本,提供了异步非堵塞的 IO 操作方式,所以人们叫它 AIO(Asynchronous IO),异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

Linux 5 种 IO 模型

Linux IO 模型中,会经历数据准备(等待数据到达并赋值到内核缓冲区),数据处理(从内核拷贝到进程)两个阶段l

  • Blocking IO 同步阻塞

进程阻塞在等待数据和处理数据阶段,啥也不干

upload successful

  • NoBlocking IO 同步非阻塞

进程轮询等待数据过程,若轮询时数据还没准备好,可以做其它事,当数据准备好之后,就阻塞在处理数据阶段,直至返回

upload successful

  • IO Multiplexing 多路复用

内核每次轮询多个进程的等待数据过程,有一个准备好了,就执行后面的数据处理过程

upload successful

  • Signal-Driven IO 信号驱动

数据准备好时,进程收到信号,然后进程进行下一步的数据处理

upload successful

  • Asynchronous IO

进程在数据准备过程中处理其它事情,当数据等待和数据处理都完成之后,内核会向进程发送通知。

upload successful

  • 五种 IO 模型比较

upload successful