NIO

4 篇文章 0 订阅

NIO 简介

NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了 NIO 框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等3个核心的组件。

NIO中的N可以理解为Non-blocking,不单纯是New。
它支持面向缓冲的,基于通道的I/O操作方法。
NIO提供了与传统BIO模型中的 SocketServerSocket 相对应的 SocketChannelServerSocketChannel 两种不同的套接字通道实现。
这两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。

对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发。

NIO的特性(NIIO与BIO的区别)

1)Non-blocking IO(非阻塞IO)

BIO流是阻塞的,NIO流是不阻塞的。

Java NIO使我们可以进行非阻塞IO操作。比如说,单线程中从通道读取数据到buffer,同时可以继续做别的事情,当数据读取到buffer中后,线程再继续处理数据。写数据也是一样的。另外,非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

Java IO的各种流是阻塞的。这意味着,当一个线程调用 read()write() 时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了

BIO流与NIO都是同步的I/O模型,意思就是指将数据从kernel中拷贝数据到进程这一操作还是同步的,会存在阻塞。
一句话来说:同步/异步是从行为角度描述事物的,而阻塞和非阻塞描述的当前事物的状态(等待调用结果时的状态)。
BIO与NIO的区别就在于阻塞与非阻塞,但是其两者却都是同步的IO模型。
阻塞不阻塞指的是进程等待调用结果时的状态(这里主要是指数据准备这一阶段),当使用NIO的进程其在等待调用结果时的状态时能够做其他的事情的,而使用BIO的进程则不行,需要一直等待,不能做其他事情。相同的是两者在数据准备好后,kernel将数据拷贝到缓存中,都是同步的,需要等待执行完成,这一阶段还是会阻塞的。不像异步,异步则不需要等待结果的返回。也就是说在整个I/O操作中,BIO和NIO都能够算是全部的异步。

需要普及下I/O的过程,需要两个步骤,一个是数据的准备,一个是数据的拷贝。
简单来说,数据I/O是数据在硬盘中与缓存中来回移动的一个过程,其中需要kernel做协调。

2)Buffer(缓冲区)

BIO 面向流(Stream oriented),而 NIO 面向缓冲区(Buffer oriented)。

Buffer是一个对象,它包含一些要写入或者要读出的数据。
与BIO不同的是,NIO是直接将数据读到或者写到缓存Buffer中进行操作的
而BIO则是将数据直接写入或者将数据直接读到Stream对象中,即使BIO中有BufferInputStream或者是BufferOutputStream流,那也只是流的包装类,是处理流,还是从从流读到缓冲区

在NIO厍中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的; 在写入数据时,写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。

最常用的缓冲区是 ByteBuffer,一个 ByteBuffer 提供了一组功能用于操作 byte 数组。除了ByteBuffer,还有其他的一些缓冲区,事实上,每一种Java基本类型(除了Boolean类型)都对应有一种缓冲区。

3)Channel (通道)

NIO 通过Channel(通道) 进行读写。是连接data数据与buffer缓存区的桥梁。

通道是双向的,可读也可写,而BIO中流stream的读写是单向的。无论读写,通道只能和Buffer交互。因为 Buffer,通道可以异步地读写。

4)Selector (选择器)

NIO有选择器,而BIO没有。

Selector是NIO中能够检测一个到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件,通过一个单独的线程可以管理多个channel,从而管理多个连接。

选择器通过使用单个线程处理多个通道。因此,它需要较少的线程来处理这些通道。线程之间的切换对于操作系统来说是昂贵的。 因此,为了提高系统效率选择器是有用的。
由于Selector管理多个Channel的特性,可以将NIO简单区分为两种:普通的NIO,和多路复用的NIO(加入了selector管理)

在普通NIO中没有使用到Selector ,那么,NIO,则会不断的向kernel发起轮询,发送“System call”询问kernel是否准备好data,还没准备好,程序则可以处理其他代码,准备好了,则会进入data copy ,将数据从kernel拷贝到进程中。

而多路复用NIO则不同,在IO中使用带了Selecter ,当并发量大的情况下,则不可能就普通NIO那样,每个线程中都不断的向kernel发起轮询,需要使用到Selector来管理所有的channel, 只要用到一个线程即可管理所有的Channel,当哪一个channel的data 准备好, 返回readable给这个channer的线程,让其进入数据 copy阶段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值