文章内容是学习过程中的知识总结,如有纰漏,欢迎指正
文章目录
前言
网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的(来自百度百科)。I/O在网络编程中更是扮演着重要的角色。
以下是本篇文章正文内容
一、什么是IO?
在计算机操作系统中,所谓的I/O
就是 输入(Input)和输出(Output),也可以理解为读(Read)和写(Write),针对不同的对象,I/O模式可以划分为磁盘IO模型和网络IO模型。
I/O 就是计算机内存与外部设备之间拷贝数据的过程
- 数据从网卡拷贝到内核空间
- 数据从内核空间拷贝到用户空间
二、I/O 中的两组概念
在I/O操作中有这么两组概念
同步/异步
,
阻塞/非阻塞
。其中
同步/异步
要和线程中的
同步线程/异步线程
要区分开,这里指的是
同步IO/异步IO
三、常见I/O模型
-
同步阻塞
-
同步非阻塞
-
I/O多路复用
-
异步
四、JAVA BIO模型
BIO是blocking I/O的简称,它是
同步阻塞型IO
,其相关的类和接口在java.io下,BIO模型简单来讲,就是服务端为
每一个请求都分配一个线程
进行处理,I/O操作都是基于流Stream的操作
存在弊端
-
线程开销
客户端的并发数与后端的线程数成1:1的比例,线程的创建、销毁是非常消耗系统资源的,随着并发量增大,服务端性能将显著下降,甚至会发生线程堆栈溢出等错误
-
线程阻塞
当连接创建后,如果该线程没有操作时,会进行阻塞操作,这样极大的浪费了服务器资源
五、JAVA NIO模型
NIO,称之为New IO 或是 non-block IO (同步非阻塞IO),这两种说法都可以,其实称之为非阻塞IO更恰当一些
NIO的三大核心组件:
Buffer(缓冲区)、Channel(通道)、Selector(选择器/多路复用器)
-
BUFFER(缓冲区)
Buffer是一个对象,包含一些要写入或者读出的数据,体现了与原I/O的一个重要区别,在面向流的I/O中,数据读写是直接进入到Steam中。
而在NIO中,所有数据都是用缓冲区处理的,读数据直接从缓冲区读,写数据直接写入到缓冲区
。
缓冲区的本质是一个数组,通常是一个字节数组(ByteBuffer),也可以使用其他类型,但缓冲
区又不仅仅是一个数组,它还提供了
对数据结构化访问以及维护读写位置等操作
-
Channel(通道)
Channel 是一个通道,管道,网络数据通过Channel读取和写入,Channel和流Stream的不同之处在于Channel是双向的,流只在一个方向上移动(InputStream/OutputStream),而Channel可以用于读写同时进行,即Channel是全双工的
-
Selector(选择器/多路复用器)
Selector会不断轮询注册在其上的Channel,如果某个Channel上面发生读或者写事件,即该Channel处于就绪状态,它就会被Selector轮询出来,然后通过selectedKeys可以获取就绪Channel的集合,进行后续的I/O操作。
六、JAVA AIO模型
在NIO中,Selector多路复用器在做轮询时,如果没有事件发生,也会进行阻塞,如何优化?
AIO是asynchronous I/O的简称,是异步非阻塞IO,该异步IO是需要依赖于操作系统底层的异步IO实现
-
AIO的基本流程
用户线程通过系统调用,告知kernel(内核)启动某个IO操作,用户线程返回。kernel内核在整个IO操作(包括数据准备、数据复制)完成后,通知用户程序,用户执行后续的业务操作
-
不足之处
- windows下实现成熟,但很少作为百万级以上或者说高并发应用的服务器操作系统来使用
- Linux 系统下,异步IO模型在2.6版本才引入,目前并不完善。所以 Linux 下,实现高并发网络编程时都是以 NIO 多路复用模型模式为主
总结
通过这篇文章,我们掌握了什么是 IO、JAVA常见的 IO 操作类型以及对应操作的原理,还有非常重要但是却很容易搞混的同步/异步、阻塞/非阻塞之间的区别。