Java与操作系统中的 I/O 模型学习

本文介绍了Java和Linux中的I/O模型,包括同步与异步、阻塞与非阻塞的概念,以及BIO、NIO和AIO的区别。详细讲解了Linux的五种I/O模型: Blocking IO、NonBlocking IO、IO Multiplexing、Signal-Driven IO和Asynchronous IO,阐述了各自的特性和工作流程。
摘要由CSDN通过智能技术生成

I/O 分类

  • 按传输数据方式:

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

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

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

  • 按输入输出方向:

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

Java 中的 I/O 种类
在这里插入图片描述

同步与异步

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

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

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

阻塞与非阻塞

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

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

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

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

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

BIO、NIO 和 AIO 的区别

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

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

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

Linux 5 种 I/O 模型

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

  • Blocking IO 同步阻塞

进程阻塞在等待数据和处理数据阶段,啥也不干
在这里插入图片描述

  • NoBlocking IO 同步非阻塞

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

当对一个非阻塞 socket 执行读操作时,如果 kernel 中的数据还没有准备好,那么它并不会 block 用户进程,而是立刻返回一个 error。用户进程需要不断地主动进行 read 操作,一旦数据准备好了,就会把数据拷贝到用户内存。
在这里插入图片描述

  • IO Multiplexing 多路复用

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

这种 IO 方式也称为 event driven IO,通过使用 select/poll/epoll 在单个进程中同时处理多个网络连接的 IO。例如,当用户进程调用了 select,那么整个进程会被 block,通过不断地轮询所负责的所有 socket,当某个 socket 的数据准备好了,select 就会返回。这个时候用户进程再调用 read 操作,将数据从 kerne l拷贝到用户进程。

在IO复用模型中,实际上对于每一个 socket,一般都设置成为 non-blocking,但是,整个用户进程其实是一直被 block 的,先是被 select 函数 block,再是被 socket IO 第二阶段 block。
在这里插入图片描述

  • Signal-Driven IO 信号驱动

数据准备好时,进程收到信号,然后进程进行下一步的数据处理
在这里插入图片描述

  • Asynchronous IO

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

在 linux 异步 IO 中,用户进程发起 read 操作之后,直接返回,去做其它的事。而另一方面,从 kernel 的角度,当它受到一个 asynchronous read 之后,kernel 会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel 会给用户进程发送一个 signal,告诉它 read 操作完成了。也就是说两个阶段都不会阻塞线程。它就像是用户进程将整个 IO 操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查 IO 操作的状态,也不需要主动的去拷贝数据。
在这里插入图片描述

五种 IO 模型比较

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值