JAVA IO : BIO NIO AIO

  • 同步异步、阻塞非阻塞概念
    • 同步与异步
    • 阻塞与非阻塞
  • IO VS NIO VS AIO
    • 面向流与面向缓冲
    • 阻塞与非阻塞IO
  • BIO、NIO、AIO的JAVA实现
  • BIO、NIO、AIO适用场景分析

同步异步、阻塞非阻塞概念

同步和异步是针对应用程序和内核的交互而言的,主要看是主动轮训内核还是等待内核通知。 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返回一个状态值。

同步与异步

  • 同步:用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪。餐厅窗口点了餐品,每过一会来问一下,我们的餐品是否准备好了。
  • 异步:指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知(异步的特点就是通知)。餐厅窗口点餐,当说明我们需要的餐品之后,然后自己可以去干别的事。当餐厅准备好了之后会通知我们。(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS) 。

阻塞与非阻塞

  • 阻塞:当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止。餐厅窗口点餐,当说明我们需要的餐品之后,窗口只会在加工完成并且送出我们需要的餐品的时候才会响应我们,在这期间,不可以做其他的事情,我们必须保持等待。

  • 非阻塞:当试图对该文件描述符进行读写时, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待。餐厅窗口点餐,当说明我们需要的餐品之后,窗口立刻响应,给我们一张小票,领票完后我们自己可以玩玩手机,或者与别人聊聊天,我们可以轮询(同步)我们的餐品是否OK或者等待通知(异步)。

IO VS NIO VS AIO

IO NIO AIO(NIO2)
面向流 面向缓冲 面向缓冲
阻塞IO 非阻塞IO 非阻塞IO
同步 同步 异步
选择器 观察者

面向流与面向缓冲

Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

阻塞与非阻塞IO

Java IO的各种流是阻塞的。这意味着,当一个线程调用read()write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

在IO设计中,我们从InputStream或 Reader逐字节读取数据。假设你正在处理一基于行的文本数据流,例如:

Name: Anna
Age: 25
Email: anna@mailserver.com
Phone: 1234567890

该文本行的流可以这样处理:

        InputStream input = null;try {input = new FileInputStream("/data/file/temp/test.txt");} catch (FileNotFoundException e) {e.printStackTrace();}BufferedReader reader = new BufferedReader(new InputStreamReader(input));try {//堵塞到读取本行数据完成String nameLine   = reader.readLine();//堵塞到读取本行数据完成String ageLine    = reader.readLine();//堵塞到读取本行数据完成String emailLine  = reader.readLine();//堵塞到读取本行数据完成String phoneLine  = reader.readLine();} catch (IOException e) {e.printStackTrace();}

一旦reader.readLine()方法返回,你就知道肯定文本行就已读完, readline()阻塞直到整行读完,这就是原因。你也知道此行包含名称;同样,第二个readline()调用返回的时候,你知道这行包含年龄等。 正如你可以看到,该处理程序仅在有新数据读入时运行,并知道每步的数据是什么。一旦正在运行的线程已处理过读入的某些数据,该线程不会再回退数据(大多如此)。

而一个NIO的实现会有所不同,下面是一个简单的例子:

        RandomAccessFile aFile = null;try {aFile = new RandomAccessFile("/data/file/temp/big.txt", "rw");} catch (FileNotFoundException e) {e.printStackTrace();}FileChannel inChannel = aFile.getChannel();//建造一块20480字节的大缓冲区ByteBuffer buf = ByteBuffer.allocate(20480);//写入文件信息到缓冲区int bytesRead = 0;try {//不会堵塞,立刻返回bytesRead = inChannel.read(buf);//查看已经读取到缓存的字节数System.out.println(bytesRead);while (bytesRead != -1) {//转为读取模式buf.flip();while(buf.hasRemaining()){// 一次读取一个字节System.out.print((char) buf.get());}//清空缓冲区buf.clear();//继续写入文件信息到缓冲区bytesRead = inChannel.read(buf);}} catch (IOException e) {e.printStackTrace();}finally {try {aFile.close();} catch (IOException e) {e.printStackTrace();}}

从通道读取字节到ByteBuffer。当这个方法调用返回时,你不知道你所需的所有数据是否全部加载完成是否都已经在缓冲区内。
结果如下

BIO、NIO、AIO的JAVA实现

  • Java BIO: 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
  • Java NIO: 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器(selector)上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  • Java AIO(NIO.2): 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,

BIO、NIO、AIO适用场景分析

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

另外,I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。

JAVA IO : BIO NIO AIO相关推荐

  1. Java IO(BIO, NIO, AIO) 总结

    文章转载自:JavaGuide 目录 BIO,NIO,AIO 总结 同步与异步 阻塞和非阻塞 1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 ...

  2. java io bio nio aio 详解

    BIO.NIO.AIO的区别: BIO就是基于Thread per Request的传统server/client实现模式, NIO通常采用Reactor模式, AIO通常采用Proactor模式, ...

  3. Java之IO,BIO,NIO,AIO知多少?

    开心一笑 [一女人:"我真不放心丈夫,他准备到湖中心水最深的地方把猫扔掉."邻居:"那有什么不放心的?"女人:"猫已回家一钟头了!"] 提出 ...

  4. Java IO BIO NIO

    Java IO BIO NIO 一.Java I/O概述 1.1 什么是流 1.2 流的分类 1.3 字符流 1.3.1 Reader 1.3.2 Writer 1.4 字节流 1.4.1 Input ...

  5. IO之 java中BIO NIO AIO原理、区别以及应用

    在本篇文章中,我们主要介绍一下java中的BIO NIO AIO,重点是NIO 先说一下同步.异步.阻塞和非阻塞. 简单来讲,同步和异步是针对内核和应用程序之间的交互而言的:阻塞和非阻塞其实是针对进程 ...

  6. IO: BIO ? NIO ? AIO?

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...

  7. Java之IO,BIO,NIO,AIO

    2019独角兽企业重金招聘Python工程师标准>>> 参考文献一 IO基础知识回顾 java的核心库java.io提供了全面的IO接口.包括:文件读写.标准设备输出等.Java中I ...

  8. java io bio nio面试题_漫画:一文学会面试中常问的 IO 问题!

    原标题:漫画:一文学会面试中常问的 IO 问题! 作者 | 漫话编程 责编 | 伍杏玲 本文经授权转载自漫话编程(ID:mhcoding) 周末午后,在家里面进行电话面试,我问了面试者几个关于IO的问 ...

  9. JAVA 中BIO,NIO,AIO的理解

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

最新文章

  1. pip 指定目录安装
  2. Java项目:中小医院信息管理系统(java+Springboot+ssm+mysql+maven+jsp)
  3. 自定义的GridView控件源代码
  4. 在编程和算法领域,有哪些经典问题
  5. git 版本操作命令大全
  6. 进程 互斥锁、队列与管道、生产者消费者模型
  7. 写代码也有“套路”-谈谈设计模式
  8. ‘cross-env‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  9. 你所不知道的JavaScript数组
  10. 互联网+创新创业大赛项目计划书,个人原创你学会了吗?
  11. 【设计鉴赏】张艺谋《影》震撼人心的海报设计
  12. TCP|IP+WIFI无线远程网络RFID|NFC读卡器HX530-Q-A系列Server网络模式与 Client网络模式设置说明
  13. 2021年N1叉车司机考试总结及N1叉车司机复审考试
  14. 网络安全之木马的工作原理及其攻击步骤
  15. Python之Pandas文本处理
  16. 上海电力大学计算机科学与技术学院,栗风永 - 上海电力大学 - 计算机科学与技术学院...
  17. echarts 3D 柱状图
  18. “华为“和“荣耀”区别日益明显,荣耀传递潮流价值观
  19. String为什么要设计成final
  20. 普元BPS产品支持环境

热门文章

  1. 计算机网络 5电路交换
  2. h5引入json_H5页面内使用JSON动画
  3. 数字图像处理笔记(一)——图像存储空间,分辨率,图像内插
  4. nginx快速配置参考
  5. 【转】Vmware 8.0注册码 序列号 key 注册方法
  6. web前端开发技巧,CSS全局样式的设置
  7. 解读:基于图卷积特征的卷积神经网络的股票趋势预测(文末赠书)
  8. External Storage
  9. Gradle 项目配置阿里云仓库
  10. 学习Python后,就业能从事哪些方向?