Java BIO、NIO、AIO

同步与异步

同步与异步的概念, 关注的是 消息通信机制

  • 同步是指发出一个请求, 在没有得到结果之前该请求就不返回结果, 请求返回时, 也就得到结果了.

比如洗衣服, 把衣服放在洗衣机里, 没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒.

  • 异步是指发出一个请求后, 立刻得到了回应, 但没有返回结果. 这时我们可以再处理别的事情(发送其他请求), 所以这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者.

比如洗衣服时, 把衣服放到洗衣机里, 我们就可以去做别的事情, 过会儿来看看有没有洗好(通过状态查询); 
或者我们设置洗衣机洗完后响铃来通知我们洗好了(回调通知)


阻塞与非阻塞

阻塞与非阻塞很容易和同步与异步混淆, 但两者关注点是不一样的. 阻塞与非阻塞关注的是 程序在等待调用结果时的状态

  • 阻塞是指请求结果返回之前, 当前线程会被挂起(被阻塞), 这时线程什么也做不了
  • 非阻塞是指请求结果返回之前, 当前线程没有被阻塞, 仍然可以做其他事情.

阻塞有个明显的特征就是线程通常是处于BLOCKED状态(BIO中的read()操作时, 线程阻塞是JVM配合OS完成的, 此时Java获取到线程的状态仍是RUNNABLE但它确实已经被阻塞了)

如果要拿同步来做比较的话, 同步通信方式中的线程在发送请求之后等待结果这个过程中应该处于RUNNABLE状态, 同步必须一步一步来完成, 就像是代码必须执行完一行才能执行下一行, 所以必须等待这个请求返回之后才可进行下一个请求, 即使等待结果的时间长, 也是在执行这个请求的过程中. 而异步则不用等上一条执行完, 可以先执行别的代码, 等请求有了结果再来获取结果.


IO模型

Java中的IO操作是JVM配合操作系统来完成的. 对于一个IO的读操作, 数据会先被拷贝到操作系统内核的缓冲区中, 然后从操作系统内核的缓冲区拷贝到应用程序的地址空间. 所以整个过程可分为两个阶段:

  1. 等待I/O数据准备好. 这取决于IO目标返回数据的速度, 如网络IO时看网速和数据本身的大小.
  2. 数据从内核缓冲区拷贝到进程内.

根据这两个阶段, 产生了常见的几种不同的IO模型: BIONIOIO多路复用AIO.

BIO

BIOBlocking I/O(阻塞 I/O), BIO整个过程如下图:

程序发送请求给内核, 然后由内核去进行通信, 在内核准备好数据之前这个线程是被挂起的, 所以在两个阶段程序都处于挂起状态.

  • BIO的特点就是在IO执行的两个阶段都被block了

NIO

NIONon-Blocking I/O(非阻塞 I/O), NIO整个过程如下图:

与BIO的明显区别是, 发起第一次请求后, 线程并没有被阻塞, 它反复检查数据是否准备好, 把原来大块不能用的阻塞时间分成了许多”小阻塞”(检查), 所以进程不断有机会被执行. 这个检查有没有准备好数据的过程有点类似于”轮询”.

  • NIO的特点就是程序需要不断的主动询问内核数据是否准备好。第一个阶段非阻塞, 第二个阶段阻塞

IO多路复用

IO多路复用(I/O Multiplexing)有selectpollepoll等不同方式, 它的优点在于单个线程可以同时处理多个网络IO.

NIO中轮询操作是用户线程进行的, 如果把这个任务交给其他线程, 则用户线程就不用这么费劲的查询状态了. IO多路复用调用系统级别的selectpoll模型, 由系统进行监控IO状态. select轮询可以监控许多socket的IO请求, 当有一个socket的数据准备好时就可以返回.

  • select: 注册事件由数组管理, 数组是有长度的, 32位机上限1024, 64位机上限2048. 轮询查找时需要遍历数组.
  • poll: 把select的数组采用链表实现, 因此没了最大数量的限制
  • epoll方式: 基于事件回调机制, 回调时直接通知进程, 无须使用某种方式来查看状态.

多路复用IO过程图:

用户线程有一段时间是阻塞的, 从上图来看, 与NIO很像, 但与NIO不一样的是, select不是等到所有数据准备好才返回, 而是只要有一个准备好就返回, 它的优势在于可以同时处理多个连接. 若连接不是很多的话, 它的效率不一定高, 可能还会更差.

Java 1.4开始支持NIO(New IO), 就是采用了这种方式, 在套接字上提供selector选择机制, 当发起select()时会阻塞等待至少一个事件返回.

  • 多路复用IO的特点是用户进程能同时等待多个IO请求, 系统来监控IO状态, 其中的任意一个进入读就绪状态, select函数就可以返回.

AIO

AIOAsynchronous I/O(异步 I/O), 这是Java 1.7引入的NIO 2.0中用到的. 整个过程中, 用户线程发起一个系统调用之后无须等待, 可以处理别的事情. 由操作系统等待接收内容, 接收后把数据拷贝到用户进程中, 最后通知用户程序已经可以使用数据了, 两个阶段都是非阻塞的. AIO整个过程如下图:

AIO属于异步模型, 用户线程可以同时处理别的事情, 我们怎么进一步加工处理结果呢? Java在这个模型中提供了两种方法:

  1. 一种是基于”回调”, 我们可以实现CompletionHandler接口, 在调用时把回调函数传递给对应的API即可
  2. 另一种是返回一个Future. 处理完别的事情, 可以通过isDone()可查看是否已经准备好数据, 通过get()方法等待返回数据.

小结

上面这几种模式, BIO整个过程都等待返回, NIOIO多路复用在第二个阶段等待返回, 因此从整个过程来看, 这三个模式都属于同步方式. AIO在整个过程中没有等待返回, 属于异步方式.

时间: 2024-10-19 01:43:01

Java BIO、NIO、AIO的相关文章

[转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)

JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11:26:13 涂有 阅读数 41728 文章标签: javaaiobionio 更多 分类专栏: java IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Server

【转】JAVA BIO与NIO、AIO的区别

Java中IO的模型分为三种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. BIO[同步阻塞] 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行. NIO[同步非阻塞] NIO本身是基于事

JAVA中IO技术:BIO、NIO、AIO

1.同步异步.阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返回一个状态值. 由上描述基本可以总结一句简短的话,同步和异步是目的,阻塞和非阻塞是实现方式. 1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了.

Java BIO、NIO、AIO 学习

先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API). 阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回). 非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你

【转】Java BIO、NIO、AIO 认知

摘要: 关于java的IO,我们很多人都停留在java原API的一些stream上面,那么在网络中提到的BIO.NIO.AIO等关键词,你是否明白这个词的含义,以及其基本的原理? 注:此文也是本搬砖者转自网络,觉得此问对三个类型的IO的形象讲解做的很好,所以翻出来和大家共同学习. 原创:http://stevex.blog.51cto.com/4300375/1284437 先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读

Java BIO、NIO、AIO基础概念

引用别人的例子理解一下概念,以银行取款为例. 同步与异步:这两个概念与消息的通知机制有关,也就是同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者,. ① 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). ② 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API). 阻塞与非阻塞:与程

Java核心(五)深入理解BIO、NIO、AIO

导读:本文你将获取到:同/异步 + 阻/非阻塞的性能区别:BIO.NIO.AIO 的区别:理解和实现 NIO 操作 Socket 时的多路复用:同时掌握 IO 最底层最核心的操作技巧. BIO.NIO.AIO 的区别是什么? 同/异步.阻/非阻塞的区别是什么? 文件读写最优雅的实现方式是什么? NIO 如何实现多路复用功能? 带着以上这几个问题,让我们一起进入IO的世界吧. 在开始之前,我们先来思考一个问题:我们经常所说的"IO"的全称到底是什么? 可能很多人看到这个问题和我一样一脸懵

JAVA SOCKET 通信总结 BIO、NIO、AIO ( NIO 2) 的区别和总结

1 同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了.2 异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知(异步的特点就是通知) 告诉朋友自己合适衣服的尺寸,大小,颜色,让朋友委托去卖,然后自己可以去干别的事.(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS)3 阻塞 所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当

Java核心(一)深入理解BIO、NIO、AIO

目标: BIO.NIO.AIO 的区别是什么? 同/异步.阻/非阻塞的区别是什么? 文件读写最优雅的实现方式是什么? NIO 如何实现多路复用功能? 一,IO的介绍: (1)IO的全称其实是:Input/Output的缩写. (2)我们通常所说的 BIO 是相对于 NIO 来说的,BIO 也就是 Java 开始之初推出的 IO 操作模块,BIO 是 BlockingIO 的缩写,顾名思义就是阻塞 IO 的意思. 1.1 BIO.NIO.AIO的区别 BIO 就是传统的 java.io 包,它是基

Java IO模型:BIO、NIO、AIO

Java IO模型:BIO.NIO.AIO 本来是打算直接学习网络框架Netty的,但是先补充了一下自己对Java 几种IO模型的学习和理解.分别是 BIO.NIO.AIO三种IO模型. IO模型的基本说明 BIO模型图 缺点: 如果有很多个Client,则会产生很多个线程.压力主要是在服务器端.客户端的压力并不大. 另外建立连接之后,并不是在时时刻刻的使用.会有空间时间. 会阻塞. NIO模型图 特点: 事件驱动 多路复用 Netty底层使用的NIO模型 AIO模型 目前还未得到广泛运用.异步