关于IO的整理
我们知道io只是输入输出,在java语言中分为同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO,现在的IO,一般是用作两种用途:一种是进行文件或者目录的操作(将不同的输入输出源抽象成流,所以流本质就是从起源到接受的有序数据,即流就是数据),另一种是进行套接字(Socket)操作(分为ServerSocket——监听其他通讯实体连接请求,是服务器端和Socket——连接到制定的服务器,是客户端)。
BIO是传统的IO,又称为阻塞性IO
java中的BIO存在两类,一共四个基类,分别是OutputStream/InputStream(字符流),Writer/Reader(字节流),后者两类是为了方便字节操作对前者进 行了封装,底层还是字符流(具体他们的区别,我们在后续的博文中比较)。
在进行文件或者目录操作的时候,将数据的接收方抽象成水管,水管中的水滴就是最小的数据传输单元(对于字节流是一个字节,对于字符流是一个字 符),通过隐式的记录指针来表示当前准备读取水滴的位置,指针自动向后移动,数据连续不断发送,每个基类中也有对应的方法对指针进行操纵,但是不能操 作读取的方向,BIO数据的传输是单向的,也就是说,不能灵活的操作流中的数据发送的方向
在进行套接字操作的时候,accept()、connect()、write()、read()调用时会产生阻塞。一个请求一个线程,并发过高,线程压力过大,会导致宕机,所以不能应对高并发,高访问量的场景。
NIO(N可以理解为new,也可以理解为NonBlock)是新IO,非阻塞IO
NIO是面向通道(channel)的,面向缓冲区(buffer)的,通道相当于提供了运算环境,缓冲区是运输数据的载体。
在进行文件或者目录操作的时候,可以通过通道或者缓冲区进行数据的读写(同一个channel中既可以读也可以写,是双向的),所有对数据的操作都是通 过缓冲区操作的。
在进行套接字操作的时候,accept()、connect()、write()、read()调用时不会产生阻塞。一个有效请求对应给一个线程,连接没有数据处理就没有线程等待。所以能应对高并发,高访问量的场景。
AIO是异步IO,Netty在之前的版本中用过,但是现在不用了,现在这项技术还没有具体的行业版。
转自其他文章:
Java对BIO、NIO、AIO的支持:
Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,
BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
另外,I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。
在比较这两个模式之前,我们首先的搞明白几个概念,什么是阻塞和非阻塞,什么是同步和异步,同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。而阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返回一个状态值。
一般来说I/O模型可以分为:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO
同步阻塞IO:在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!
同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。
异步阻塞IO:此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!
异步非阻塞IO:在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。
注:
阻塞与非阻塞是指这个方法在执行的时候是否阻塞程序的继续执行其他与客户端和服务器端无关程序。
附:BIO阻塞产生与放开的条件
* accept()会产生阻塞
* Listens for a connection to be made to this socket and accepts
* it. The method blocks until a connection is made.
* 当一个客户端连入的时候,阻塞放开,如果没有客户端连入,就会产生阻塞
* read()会产生阻塞
* This method
* blocks until input data is available, the end of the stream is detected,
* or an exception is thrown.
* 当有数据可读时,阻塞放开。
* write()也会产生阻塞,一直往出写数据,但是没有任何一方读这个数据的时候
* 写到一定量就会产生阻塞。(是写到网卡的设备缓冲区里)
* connect()一会产生阻塞,
* Connects this socket to the server with a specified timeout value.
* A timeout of zero is interpreted as an infinite timeout. The connection
* will then block until established or an error occurs.
* 直到成功连入服务端或抛异常,阻塞放开
关于IO的整理的更多相关文章
- socket.io入门整理教程
socket.io入门整理 发布于 5 年前 作者 dtrex 124983 次浏览 最后一次编辑是 1 年前 我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写 ...
- WinRT IO相关整理
虽然一般UWP开发还是依赖.Net for UWP,但有时还是需要调用WinRT API.特别是在IO部分,WinRT有着和.Net似曾相识但又不尽相同的接口.在此对经常用到的一些地方进行一下整理. ...
- socket.io入门整理
我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单的聊天程序. 最最开始 先安装socket.io: 1 npm install socket.io 利用Nod ...
- Java IO流整理Rick
Java 流IO部分: Console 控制台信息读取// ----------- Console Begin // ------------ 部分代码 Console cons ; char[] ...
- java IO流整理
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- IO知识点整理(序列化,管道流,数据流,字节数组流,与编码)
一:序列化的问题 1.序列号的使用问题 关于在序列化中的序列号的使用问题,一般要是使用. 因为,每次要序列化的类产生都会产生一个一个新的序列号,如果将这个类的程序修改后,就会产生新的序列号,以前序列化 ...
- IO知识点整理(文件File类的使用)
一: 1.API 2.构造函数的程序 注意这集中构造函数的特点. 同时,字段separator的使用. import java.io.File; public class Test101 { publ ...
- IO知识点整理(四种基类的使用)
一:介绍 1.两种基类 字节流 InputStream,OutputStream 字符流 Reader,Writer 二:字符流的基本方法(文字的处理比较常见) 1.Writer的API 2.File ...
- Java 持久化之 -- IO 全面整理(看了绝不后悔)
目录: 一.java io 概述 什么是IO? IO包括输入流和输出流,输入流指的是将数据以字符或者字节形式读取到内存 分为字符输入流和字符输入流 输入流指的是从内存读取到外界 ,分为字符输入流和字节 ...
随机推荐
- jQuery轮播图--不使用插件
说明:引入jquery.min.js 将轮播图放入imgs文件夹 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...
- mysql 多列索引学习-经典实例
索引优化 ,b-tree假设某个表有一个联合索引(c1,c2,c3,c4) 以下 只能使用该联合索引的c1,c2,c3部分A. where c1 = x and c2 = x and c4>x ...
- Spring基础篇——Spring的AOP切面编程
一 基本理解 AOP,面向切面编程,作为Spring的核心思想之一,度娘上有太多的教程啊.解释啊,但博主还是要自己按照自己的思路和理解再来阐释一下.原因很简单,别人的思想终究是别人的,自己的理解才是 ...
- ES6基本使用
var let 度可用于声明变量. 区别:1.let:只在let命令所在代码块内有效 2.let 不存在变量提升(内部影响不到外部) var b = []; ;j<;j++){ let d=j; ...
- Mac 怎么通过自带终端连接linux服务器
简单来说,就两步骤 · 打开Mac终端,切换到root权限下 切换root权限: sudo -i ·通过ssh命令连接linux服务器 ssh root@127.0.0.1 root是账户名,@后面的 ...
- centos7 删除swap
https://www.refmanual.com/2016/01/08/completely-remove-swap-on-ce7/#.W8AaSRMzaRs 删除不干净,启动不起来的情况下.需要从 ...
- 7C - 折线分割平面
我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目.比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示. Input ...
- scrapy 爬取智联招聘
准备工作 1. scrapy startproject Jobs 2. cd Jobs 3. scrapy genspider ZhaopinSpider www.zhaopin.com 4. scr ...
- Lonsdor K518ISE SCION 2011-2018 Models Enabled!
Lonsdor released the Lonsdor K518ISE Key Programmer update announcement on 14-03-2019, saying it can ...
- JAVA实训第四次作业
编写"电费管理类"及其测试类. 第一步 编写"电费管理"类 私有属性:上月电表读数.本月电表读数 构造方法:无参.2个参数 成员方法:getXXX()方法.se ...