基础篇--Java IO--概览
字符流、字节流、输入流、输出流
Java 中使用IO(输入输出)来读取和写入,读写磁盘文件、内存、网络数据。输入输出是相对内存而言,往内存中读数据就为输入流,从内存中往外写就是输出流。
根据处理类型分为字符流、字节流。
字节流处理所有类型数据,以Stream结尾;
字符流处理文本数据,以Reader、Writer结尾;
Java IO类见下图:
同步、异步、阻塞、非阻塞
synchronous、asynchronous、blocking、non-blocking同步、异步关注的是消息通信机制
同步,是在发起调用后,在得到结果前,该调用不会返回。等到调用返回后,就能拿到返回值。调用者主动等待调用结果。
异步, 是在发起调用后,调用直接返回,所以无返回结果。后续通过状态、回调通知调用者。阻塞、非阻塞关注的是程序在等待调用结果(返回值、消息)时的状态
阻塞调用,是指在调用结果返回前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用,是指在调用结果返回前,该调用不会阻塞当前线程。换句话说:
同步、异步区别:是否需要等待调用结果,才能进行下一步。
阻塞、非阻塞:进程\线程要访问的数据就绪前,进程\线程是否需要等待。
Linux的5种IO模型
- 阻塞IO模型
- 非阻塞IO模型
- IO复用模型
- 信号驱动IO模型
- 异步IO模型
1.阻塞IO模型
Linux中,默认情况下socket是阻塞的,一个典型的读操作流程如下:
当用户进程调用了recvfrom这个系统调用,kernel就开始了I/O的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。
当kernel一直等到数据准备好了,它就会将数据从kernel系统缓冲区中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。所以,blocking IO的特点就是在I/O执行的两个阶段都是block。
Windows Socket API
socket()函数和WSASocket()函数创建套接字时,默认的套接字是阻塞的。线程会阻塞等待,直到Windows Sockets API执行完成。
bind()、listen()函数,不会阻塞线程
可能会阻塞套接字的Windows Socket API调用分为4类
输入操作:recv()、recvfrom()、WSARecv()和WSARecvfrom()函数。以阻塞套接字为参数的该函数接受数据。如果此时套接字缓冲区中无数据,则调用线程一直睡眠到数据到来
输出操作:send()、sendto()、WSASend()和WSASendto()函数。调用该函数发送数据。如果套接字缓冲区无可用空间,则调用线程会一直睡眠到有可用空间。
接受连接:accept()和WSAAcept()函数。以阻塞套接字为参数的该函数等待接受对方的连接请求。无则线程休眠。
外出连接:connect()和WSAConnect()函数。对于TCP连接,客户端以阻塞套接字为参数,调用该函数向服务器发起连接。
该函数在接收到服务器的应答前,不会返回。 这意味着TCP连接总会等待至少到服务器的一次往返时间。阻塞模式的套接字,开发实现简单。但是并发能力较弱,扩展性弱。
2.非阻塞IO模型
Linux下,可以设置socket为non-blocking。这种情况下的读取流程如下:
用户进程调用recvfrom()时,如果kernal数据还未准备好,则直接返回error。用户线程不断重试,直到kernal准备好后,就马上将数据拷贝到用户内存,然后返回。所以这种模式下,用户线程需要不断主动询问kernal数据好了没。
3.IO复用模型(IO multiplexing)
IO复用模型又称event driven I/O,是在实际中使用最多的I/O模型。基本原理是select/epoll这个方法不断轮训所负责的socket,当某个socket有数据到达时,就通知用户线程。流程如下:
当用户线程调用select(),整个线程就会block,同时kernal会监听所有select负责的socket,一旦有socket的数据准备好了,select()就会返回。这时候用户线程再去调用read()操作,将数据从kernal拷贝到用户线程。
当线程数量较少时,这种方式可能比阻塞I/O模型效率更低,因为多了select()操作。select/epoll的优势是能处理更多的连接,在高并发场景效率更高。
4.信号驱动I/O模型(Signal-driven I/O)
首先我们需要允许套接字使用信号驱动IO,并安装一个信号处理函数,然后进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,在信号处理函数中调用IO操作函数处理数据。流程如下:(这种模型在实际中并不常用)
5.异步I/O模型(Asynchronous I/O)
这种模型不常用,流程如下:
用户线程发起read操作后,立刻就可以去做别的事情。从kernal角度,当它收到一个asynchroous read请求之后,会立刻返回,不会阻塞用户进程。然后kernal等待数据准备完成,将数据拷贝到用户内存,之后给用户进程发送一个signal,告诉它read操作完成了。
总结
1:blocking和non-blocking的区别
blocking IO会阻塞住对应的进程直到操作完成,non-blocking IO在kernal还未准备好数据的时候,直接返回。
1:synchronous I/O 和asynchronous IO的区别
区别在于synchronous I/O做I/O操作的时候会将进程阻塞。所以,blocking I/O,non-blocking I/O,I/O multiplexing,Signal-driven I/O都属于synchronous I/O,只有Asynchronous I/O属于asynchronous IO
扩展:select、poll、epoll简介
epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现。
1.select
select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:
单个进程可监视的fd数量被限制,即能监听端口的大小有限:
一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。32位机默认是1024个。64位机默认是2048对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低:
当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
2.poll
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。
它没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有一个缺点:1. 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义 2. poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd
3.epoll
epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。
epoll的优点:没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口)
效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数
即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销
select、poll、epoll 区别
select | 内核需要将消息传递到用户空间,都需要内核拷贝动作 |
---|---|
poll | 同上 |
epoll | epoll通过内核和用户空间共享一块内存来实现 |
4、Linux I/O模型总结:
综上,在选择select,poll,epoll时要根据具体的使用场合以及这三种方式的自身特点:
1、表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。
2、select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
基础篇--Java IO--概览相关推荐
- Java基础篇--Java 数组
Java基础篇--Java 数组 Java 数组 声明数组变量 创建数组 处理数组 For-Each 循环 数组作为函数的参数 数组作为函数的返回值 多维数组 多维数组的动态初始化(以二维数组为例) ...
- JavaSE基础篇--Java SE语法02--基本语法
JavaSE基础篇 Java SE语法02 HelloWorld 基本语法 流程控制 方法 数组 基本语法 标识符 关键字 数据类型 运算符 数据类型转换 运算后结果的数据类型 Java SE语法02 ...
- Java基础篇:IO流
文章目录 一.File类的使用 File类的概述 File类的实例化 File类的常用方法 二.IO流原理及流的分类 Java IO原理 流的分类 流的体系结构 输入.输出的标准化过程 三.节点流(文 ...
- 图学java基础篇之IO
java io体系 如图可以看出,java的io按照包来划分的话可以分为三大块:io.nio.aio,但是从使用角度来看,这三块其实揉杂在一起的,下边我们先来概述下这三块: io:主要包含字符流和字节 ...
- 【JAVA基础篇】IO流
一.流的概念 "对语言设计人员来说,创建好的输入/输出系统是一项特别困难的任务." ――<Think in Java> 无论是系统.还是语言的设计中IO的设计都是异常复 ...
- Java IO篇 Java IO编程
Java IO 一.java io 概述 1.1 相关概念 二.Java IO类库的框架 2.1 Java IO的类型 2.2 IO 类库 三.Java IO的基本用法 3.1 Java IO :字节 ...
- 【Java基础】Java IO编程:输入输出流、内存流、打印流、缓冲流BufferedReader、扫描流Scanner、序列化与反序列化
文章目录 第11章.Java IO编程 11.1 文件操作类:File 11.2 字节流与字符流 字节输出流:OutputStream OutputStream类 FileOutputStream类 ...
- java基础-4 JAva IO
JAva IO File类 File类介绍: 它是文件和目录路径名的抽象表示文件和目录是可以通过File封装成对象的对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存 ...
- 「ML 基础篇」机器学习概览
文章目录 1. 什么是机器学习 2. 引入机器学习 3. 应用场景 4. 机器学习分类 4.1. 有无人类监督 4.2. 是否增量学习 4.3. 泛化方式 5. 主要挑战 6. 测试与验证 1. 什么 ...
最新文章
- 焊接工具DIY电焊机,自动触发笔,手持电焊笔
- php htmlentities函数的问题
- 【大会】看案例,选方案
- 前端学习(6):javascript简介
- 【网络流24题】餐巾计划问题(费用流)
- C++ 智能指针shared_ptr、weak_ptr的简单实现
- Linux之yum软件管理
- 如何制作多合一Windows镜像
- MATLAB鲁棒控制器实现
- 遇到的几个运放精密整流电路
- 计算机网络微课笔记03
- c语言间接寻址与指针,C语言中指针是不是用汇编的间接寻址实现的?
- 2021年职业院校技能大赛“网络安全”项目江西省A模块
- 华人最多的和比例最高的国家
- DLP是如何防止数据泄露的?
- 一文解析推特上最常见的加密骗局
- TCP/IP,TCPsocket,tcp协议的特点,tcp报文段最长字节数,tcp头内容,确认号和超时时限的设定细节,tcp协议是GBN和SR的混合体,
- CS61A Lab 1
- golang 撤回_Activiti6.0版本流程撤回、跳转、回退等操作
- gta5线上模式进不去云服务器,gta5ol线上连不上服务器|云端存档同步发生错误
热门文章
- 关联规则java代码_重量挖掘关联规则挖掘方法,哪个大神可以将以下伪代码转换为Java代码?...
- pythonrequests说明_解决Python requests 报错方法集锦
- 服务器线程数一直增加,.NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长...
- c++ long 转 short_C精品编程之——C语言的数据类型、运算符、表达式,精品课程...
- 你永远都不知道你老公可以多幼稚......
- 假如你学过高数,那你这一辈子都不会忘记这个人
- 数学界的高冷之王,N次拒绝巨额奖金:我穷,但是我不缺钱。。。
- mysql sleep详解_sql注入详解(二)
- float型y取值在1.0c语言表达式,2011年全国计算机二级C语言模拟试题及答案(14)...
- c语言字符比较思路,C语言讲解思路资料