Java中IO框架

1、知识体系

在这里插入图片描述

2、NIO(New IO)

NIO(New IO),它是一种同步非阻塞I/O模型,也是 I/O多路复用的基础,在高并发,大量连接等场景有着比较明显的优势。

NIO是一种基于通道和缓冲区的I/O方式,主要有三大核心组件:Channel(通道),Buffer(缓冲区), Selector(选择器)。当线程对数据进行操作时,先从Channel将数据读取到Buffer,或者从缓冲区将数据写入到Channel。Selector用于监听多个通道的事件,来通知连接打开,数据到达等操作,一个线程可以监听多个数据通道。
在这里插入图片描述

2.1、缓存区(Buffer)

通常情况下,操作系统的一次写操作分为两步 : 1. 将数据从用户空间拷贝到系统空间。 2. 从系统空间往网卡写。同理,读操作也分为两步: ① 将数据从网卡拷贝到系统空间; ② 将数据从系统空间拷贝到用户空间。

对于NIO来说,缓存的使用可以使用 DirectByteBuffer(堆外)和HeapByteBuffer(堆内) (DirectByteBuffer底层实现是数组)。如果使用了DirectByteBuffer,一般来说可以减少一次系统空间到用户空间的拷贝。但Buffer创建和销毁的成本更高,更不宜维护,通常会用内存池来提高性能。

2.2、通道(Channel)

通道(Channel):由java.nio.channels包定义的。Channel表示IO源与目标打开的连接。Channel类似于传统的“流”。只不过Channel本身不能直接访问数据,Channel只能与Buffer进行交互。

Channel和传统IO中的Stream很相似。主要区别在于:通道它是双向的,它既可以进行读,也可以进行写。但Stream只能进行单向操作,例如InputStream只能进行读取操作,OutputStream只能进行写操作。

2.3、选择器(Selector)

选择器(Selector)是SeIectabIeChannIe对象的多路复用器,Selector可以同时监控多个SelectableChannel 的IO状况,也就是说,利用Selector可使一个单独的线程管理多个Channel,其中在Win系统里面Selector默认的是Select函数,Linux默认的是epoll函数。

Selector是非阻塞IO的核心

在这里插入图片描述

//1.获取通道
ServerSocketChannel ssChannel = ServerSocketChannel.open();
//2.切换非阻塞模式
ssChannel.configureBlocking(false);
//3.绑定连接
ssChannel.bind(new InetSocketAddress(9898));
//4.获取选择器
Selector selector = Selector.open();
//5.将通道注册到选择器上,并且指定“监听接收事件”
ssChannel.register(select,SelectionKey.OP_ACCEPT);

2.4、Select函数和EPOLL函数、POLL函数

(1)Select函数

(2)EPOLL函数

(3)POLL函数

5、Linux五种IO模型

5.1、阻塞式IO(BIO)

在这里插入图片描述
应用进程 通过recvfrom()从socket接受数据报被阻塞,直到数据复制到应用进程缓冲区中才返回。
注意:recvfrom从socket接收数据,select是从文件系统读取数据。

5.2、非阻塞式IO(NIO)

在这里插入图片描述
应用进程 执行系统调用之后,内核返回一个错误码。应用进程可以继续执行,但是 需要不断的 执行系统调用来获知 I/O 是否完成,这种方式称为轮询(polling)。

5.3、IO多路复用

在这里插入图片描述
上面介绍的I/O模型都是应用程序直接发起I/O操作,而I/O Multiplexing首先应用程序先向kernel发起system call(select()),传入file descriptor和事件(readable、writable等)让kernel监测,当其中一个或多个fd数据就绪,就会返回结果,程序再发起真正的I/O操作(resvfrom());

5.4、信号驱动IO

在这里插入图片描述
这种信号驱动的I/O并不常见,从图片可以看到它第一次发起system call不会阻塞进程,kernel的数据就绪后会发送一个signal给进程。进程发起真正的IO操作。

5.5、异步IO(AIO)

在这里插入图片描述
异步I/O,即I/O操作不会引起进程阻塞。请看上图,发起aio_read请求后,kernel会直接返回。等数据就绪,发送一个signal到process处理数据。

注意:程序不需要再次发起读取数据的system call,因为kernel会把数据复制到user space再通知进程处理,整个过程不存在任何阻塞。

特别注意: select、poll、epoll并不是I/O操作,read、recvfrom这些才是。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值