在Java1.4之前的版本,Java对I/O的支持并不完善,开发人员在开发高性能I/O程序的时候,会面临以下几个问题:

1、没有数据缓存区,I/O性能存在问题

2、没有C/C++通道的概念,输入和输出流是相互独立的不能复用

3、同步阻塞式I/O通信(BIO),造成线程资源被长时间阻塞(致命缺陷)

4、硬件可移植性差,支持的字符集编码有限

根据UNIX网络编程的概念,I/O模型有五种

详情请查看这篇文章

UNIX五种网络I/O模型

在没有JavaNIO之前呢,基于Java的所有的所有的Socket通信都采用了同步阻塞式模型(BIO)这种请求<->应答的通信模式降低了开发难度,但是在性能和可靠性方面存在巨大缺陷,因此大型应用服务器都是C/C++语言开发,因为他们可以直接操作系统提供的异步的I/O或者是AIO能力。当并发访问量增大,响应时间延迟增大之后,采用JavaBIO开发的服务器只能通过硬件扩容来满足高并发和低延时,极大增加了企业成本。

正是由于JavaBIO的不足,Java1.4版本之后提供了新的NIO库,支持非阻塞式I/O操作。

JavaNIO提供了很多的异步I/O开发和API类库,主要的类和接口如下:

进行异步I/O操作的缓存区ByteBuffer

进行异步I/O操作的管道Pipe

进行各种I/O操作(异步或者同步)的Channel,包括ServerSocketChannel和SocketChannel

多种字符集编码能力和解码能力

实现非阻塞I/O操作的选择器Selector

基于流行Perl实现的正则表达式库

了解NIO必须先了解几个概念

什么是同步
什么是异步
什么是阻塞
什么是非阻塞
什么是同步阻塞
什么是同步非阻塞
什么是异步阻塞
什么是异步非阻塞

技术语言解释:

同步:当一个进程去访问另一个进程时,必须得到一个结果(指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪)

异步:当一个进行访问另一个进程时时,不用立刻给结果,我会告诉你一个信息,你把结果放在这里,通知我即可(异步I/O就是Java将I/O读写操作委托给操作系统,告诉操作系统将数据放到哪个缓存区,数据大小)

阻塞:当一个进程去操作某个资源时发现这个资源不在或者暂时不可操作,那么这个进程就一直等,等可以操作

非阻塞:当进程发现没有资源可操作的时候立刻返回读写函数,而不会等待

生活中的例子:

同步:比如电话好友,那么无论打通还是打不通,都会得到回应,(用户接通了,用户正在通话,用户已关机等信息)

异步:比如叫餐,我们APP下单之后就可以做其他的事情,你只需要告诉地址,电话,食物到了送餐员会打电话通知你

阻塞:比如收费站堵车,这个就最能代表阻塞,你只能等着啥干不了

非阻塞:比如到银行排队办理业务,那么我们会拿一张排号小票,就可以去做其他事情,到号就会叫你!

网上有一个例子

同步阻塞:到饭店吃饭点餐,在那里等着不停的问,菜好了吗?菜好了吗?

同步非阻塞:点完餐,直接去打球,不过你需要隔一段时间来问一次,菜好了吗?

异步阻塞:菜做好饭店打电话给你让你亲自去拿。

异步非阻塞:菜做好,饭店直接送到球场

所以我们归纳:

同步和异步是针对应用程序和内核的交互而言的,

1、同步指的是用户进程触发I/O操作并等待或者轮询的去查看I/O操作是否就绪,

2、异步是指用户进程触发I/O操作以后便开始做自己的事情,而当I/O操作已经完成的时候会得到I/O完成的通知。

阻塞和非阻塞是针对于进程在访问数据的时候,根据I/O操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,

1、阻塞方式下读取或者写入函数将一直等待

2、而非阻塞方式下,读取或者写入函数会立即返回一个状态值。

所以,I/O操作可以分为3类:同步阻塞(即早期的I/O操作)、同步非阻塞(NIO)、异步(AIO)。

BIO

在JDK1.4之前,用Java编写网络请求,都是建立一个ServerSocket,然后,客户端建立Socket时就会询问是否有线程可以处理,如果没有,要么等待,要么被拒绝。即:一个连接,要求Server对应一个处理线程。

NIO

在Java里的由来,在JDK1.4及以后版本中提供了一套API来专门操作非阻塞I/O,我们可以在java.nio包及其子包中找到相关的类和接口。由于这套API是JDK新提供的I/O API,因此,也叫New I/O,这就是包名nio的由来。这套API由三个主要的部分组成:缓冲区(Buffers)、通道(Channels)和非阻塞I/O的核心类组成。在理解NIO的时候,需要区分,说的是New I/O还是非阻塞IO,New I/O是Java的包,NIO是非阻塞IO概念。这里讲的是后面一种。

NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题: 在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。

NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。
也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。

AIO

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。
即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。
在JDK1.7中,这部分内容被称作NIO.2,主要在java.nio.channels包下增加了下面四个异步通道:

AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
其中的read/write方法,会返回一个带回调函数的对象,当执行完读取/写入操作后,直接调用回调函数。

【NIO】之IO和NIO的区别的更多相关文章

  1. Java NIO:IO与NIO的区别 -阿里面试题

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

  2. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  3. Java NIO:IO与NIO的区别

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

  4. 【NIO】IO与NIO的区别

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

  5. Java IO 和 NIO

    昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...

  6. 理解IO、NIO、 AIO

    转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...

  7. Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?

    IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...

  8. Java NIO学习笔记九 NIO与IO对比

    Java NIO与IO Java nio 和io 到底有什么区别,以及什么时候使用nio和io,本文做一个比较. Java NIO和IO之间的主要区别 下表总结了Java NIO和IO之间的主要区别, ...

  9. Java NIO系列教程(十一) Java NIO 与 IO

    Java NIO系列教程(十一) Java NIO与IO 当学习了 Java NIO 和 IO 的 API 后,一个问题马上涌入脑海: 我应该何时使用 IO,何时使用 NIO 呢?在本文中,我会尽量清 ...

  10. Java NIO与IO的区别和比较

    传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...

随机推荐

  1. Python之路PythonNet,第一篇,网络1

    pythonnet   网络1 ARPAnet(互联网雏形)--->  民用 ISO(国际标准化组织)--->网络体系结构标准 OSI模型 OSI : 网络信息传输比较复杂需要很多功能协同 ...

  2. [LeetCode&Python] Problem 167. Two Sum II - Input array is sorted

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  3. [LeetCode&Python] Problem 383. Ransom Note

    Given an arbitrary ransom note string and another string containing letters from all the magazines, ...

  4. Unity 3D-Navigation网格导航系统使用教程

    Unity自带导航系统 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心创 ...

  5. HDU - 1174:爆头 (三维平面点到射线的距离)

    pro:给定警察的射击位置,设计方向,敌人的位置,敌人的头部半径,问子弹是否可以射到头部. sol:即问头部中点到子弹射线的距离是否小于等于头部半径. 和二维的点到直线一样的操作. det/dot: ...

  6. 将button或者input角变为圆弧

    style="border-radius:5px;" input框时,不能用type属性

  7. django ---Auth模块

    Auth模块 本文目录 1 Auth模块是什么 2 auth模块常用方法 3 扩展默认的auth_user表 回到目录 1 Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们在开 ...

  8. Java 中各种空(""、\u0000、null)的区别?

  9. 被卡住的2个问题:1.输入url不执行后台的java方法 2.改了jsp页面,再次请求还是以前的那个页面

    1.问题 一个子项目,它的java代码都是打包到磁盘这个文件夹  D://commlib java代码改了之后,也是打包到这个文件夹里,刷新就可看见改了的. 要想子项目能运行,必须在主项目中从/com ...

  10. ipfs cluster 模式部署使用(docker-compose 环境运行)

    ipfs 点对点的分布式文件系统,官方提供了集群模式运行的docker 镜像,以及docker-compose 文件 所以测试下 环境准备 docker-compose   version: '3.4 ...