Java BIO、NIO、AIO
同步与异步
同步与异步
的概念, 关注的是 消息通信机制
同步
是指发出一个请求, 在没有得到结果之前该请求就不返回结果, 请求返回时, 也就得到结果了.
比如洗衣服, 把衣服放在洗衣机里, 没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒.
异步
是指发出一个请求后, 立刻得到了回应, 但没有返回结果. 这时我们可以再处理别的事情(发送其他请求), 所以这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者.
比如洗衣服时, 把衣服放到洗衣机里, 我们就可以去做别的事情, 过会儿来看看有没有洗好(通过状态查询);
或者我们设置洗衣机洗完后响铃来通知我们洗好了(回调通知)
阻塞与非阻塞
阻塞与非阻塞
很容易和同步与异步
混淆, 但两者关注点是不一样的. 阻塞与非阻塞
关注的是 程序在等待调用结果时的状态
阻塞
是指请求结果返回之前, 当前线程会被挂起(被阻塞), 这时线程什么也做不了非阻塞
是指请求结果返回之前, 当前线程没有被阻塞, 仍然可以做其他事情.
阻塞
有个明显的特征就是线程通常是处于BLOCKED
状态(BIO中的read()
操作时, 线程阻塞是JVM配合OS完成的, 此时Java获取到线程的状态仍是RUNNABLE
但它确实已经被阻塞了)
如果要拿同步
来做比较的话, 同步通信方式中的线程在发送请求之后等待结果这个过程中应该处于RUNNABLE
状态, 同步必须一步一步来完成, 就像是代码必须执行完一行才能执行下一行, 所以必须等待这个请求返回之后才可进行下一个请求, 即使等待结果的时间长, 也是在执行这个请求的过程中. 而异步
则不用等上一条执行完, 可以先执行别的代码, 等请求有了结果再来获取结果.
IO模型
Java中的IO操作是JVM配合操作系统来完成的. 对于一个IO的读操作, 数据会先被拷贝到操作系统内核的缓冲区中, 然后从操作系统内核的缓冲区拷贝到应用程序的地址空间. 所以整个过程可分为两个阶段:
- 等待I/O数据准备好. 这取决于IO目标返回数据的速度, 如网络IO时看网速和数据本身的大小.
- 数据从内核缓冲区拷贝到进程内.
根据这两个阶段, 产生了常见的几种不同的IO模型: BIO
, NIO
, IO多路复用
和AIO
.
BIO
BIO
即Blocking I/O
(阻塞 I/O), BIO整个过程如下图:
程序发送请求给内核, 然后由内核去进行通信, 在内核准备好数据之前这个线程是被挂起的, 所以在两个阶段程序都处于挂起状态.
- BIO的特点就是在IO执行的两个阶段都被block了
NIO
NIO
即Non-Blocking I/O
(非阻塞 I/O), NIO整个过程如下图:
与BIO的明显区别是, 发起第一次请求后, 线程并没有被阻塞, 它反复检查数据是否准备好, 把原来大块不能用的阻塞时间分成了许多”小阻塞”(检查), 所以进程不断有机会被执行. 这个检查有没有准备好数据的过程有点类似于”轮询”.
- NIO的特点就是程序需要不断的主动询问内核数据是否准备好。第一个阶段非阻塞, 第二个阶段阻塞
IO多路复用
IO多路复用(I/O Multiplexing
)有select
, poll
, epoll
等不同方式, 它的优点在于单个线程可以同时处理多个网络IO.
NIO
中轮询操作是用户线程进行的, 如果把这个任务交给其他线程, 则用户线程就不用这么费劲的查询状态了. IO多路复用
调用系统级别的select
或poll
模型, 由系统进行监控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
AIO
即Asynchronous I/O
(异步 I/O), 这是Java 1.7
引入的NIO 2.0
中用到的. 整个过程中, 用户线程发起一个系统调用之后无须等待, 可以处理别的事情. 由操作系统等待接收内容, 接收后把数据拷贝到用户进程中, 最后通知用户程序已经可以使用数据了, 两个阶段都是非阻塞的. AIO整个过程如下图:
AIO
属于异步模型, 用户线程可以同时处理别的事情, 我们怎么进一步加工处理结果呢? Java在这个模型中提供了两种方法:
- 一种是基于”回调”, 我们可以实现
CompletionHandler
接口, 在调用时把回调函数传递给对应的API即可 - 另一种是返回一个
Future
. 处理完别的事情, 可以通过isDone()
可查看是否已经准备好数据, 通过get()
方法等待返回数据.
小结
上面这几种模式, BIO
整个过程都等待返回, NIO
和IO多路复用
在第二个阶段等待返回, 因此从整个过程来看, 这三个模式都属于同步方式. AIO
在整个过程中没有等待返回, 属于异步方式.
Java BIO、NIO、AIO的更多相关文章
- [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)
JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...
- JAVA BIO与NIO、AIO的区别
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...
- 【转】JAVA BIO与NIO、AIO的区别
Java中IO的模型分为三种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. BIO[同步阻塞] 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Ser ...
- Java BIO、NIO、AIO 学习(转)
转自 http://stevex.blog.51cto.com/4300375/1284437 先来个例子理解一下概念,以银行取款为例: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Ja ...
- JAVA中IO技术:BIO、NIO、AIO
1.同步异步.阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作 ...
- Java IO 之 BIO、NIO、AIO
1.BIO.NIO.AIO解释 Java BIO : 同步并阻塞 (Blocking IO) 一个连接一个线程 即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不 ...
- Java提高班(五)深入理解BIO、NIO、AIO
导读:本文你将获取到:同/异步 + 阻/非阻塞的性能区别:BIO.NIO.AIO 的区别:理解和实现 NIO 操作 Socket 时的多路复用:同时掌握 IO 最底层最核心的操作技巧. BIO.NIO ...
- Java网络通信方面,BIO、NIO、AIO、Netty
码云项目源码地址:https://gitee.com/ZhangShunHai/echo 教学视频地址:链接: https://pan.baidu.com/s/1knVlW7O8hZc8XgXm1dC ...
- 以Java的视角来聊聊BIO、NIO与AIO的区别?
转: 以Java的视角来聊聊BIO.NIO与AIO的区别? 飞丫玲丫 17-07-2623:10 题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? BIO(Blocking I ...
- Java BIO、NIO、AIO 学习
正在学习<大型网站系统与JAVA中间件实践>,发现对BIO.NIO.AIO的概念很模糊,写一篇博客记录下来.先来说个银行取款的例子: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO ...
随机推荐
- 1030 Travel Plan Dijkstra+dfs
和1018思路如出一辙,先求最短路径,再dfs遍历 #include <iostream> #include <cstdio> #include <vector> ...
- 代码图片转文本--阿里VS度娘
最近看vue的书,居然没有提供源代码,一堆的CSS真不想手工录入,于是用手机找APP去转.发现广告普遍,于是找找网上相关的API,结果百度和阿里都有在线的API提供,于是好奇其能力如何.如于用以下两图 ...
- VC6 LINK : fatal error LNK1168: cannot open Debug/Test.exe for writing
在使用VC++运行程序时,第一次没有任何问题,但是当再次运行时就会出现:LINK : fatal error LNK1168: cannot open Debug/Test.exe for writi ...
- ubuntu installs matlab2017a
cd mkdir matlab sudo mount -o loop *1.iso matlab sudo ./matlab/install ... sudo mount -o loop *2.iso ...
- xmlhttprequest readyState 属性的五种状态
关于readystate五个状态总结如下: readyState 状态 状态说明(0)未初始化此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备.值 ...
- Oracle数据库---用户与角色
Oracle数据库---用户与角色 2019年02月26日 10:56:10 俊杰梓 阅读数:21 标签: 数据库 更多 个人分类: 数据库 版权声明:版权所有,转载请注明出处.谢谢 https: ...
- JS 将canvas画布保存到本地
<!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...
- 00SQL表字段说明
SELECT d.name 表名 , a.colorder 字段序号 , a.name 字段名 , ISNULL(g.[value], '') AS 字段说明 , ( CASE WHEN COLUMN ...
- ASP.NET MVC项目中App_Code目录在程序应用
学习ASP.NET MVC,如果你是开发ASP.NET MVC项目的,也许你去为项目添加前ASP.NET项目的APP_Code目录,在这里创建与添加的Class类,也许你无法在MVC项目所引用. 那这 ...
- Java核心技术卷一基础知识-第10章-部署应用程序和applet-读书笔记
第10章 部署应用程序和applet 本章内容: * JAR文件 * Java Web Start * applet * 应用程序首选项存储 10.1 JAR文件 一个JAR文件既可以包含类文件,也可 ...