NIO 非阻塞IO

NIO与IO的区别

NIO 特点:非阻塞,面向缓冲区
IO 特点:阻塞式,面向流

阻塞与非阻塞

java io 是阻塞式的,当一个线程调用read 或者write方法后开始阻塞,直到读取到数据或者写入数据完成,该线程一直处于阻塞状态不能做其他事情。
java nio 通过选择器实现非阻塞式IO,通过一个专门的选择器线程来监视读请写请求是否已经具备完整条件。
非阻塞读:如某个线程发送一个读请求,则它只能获取到当前可用的数据,如果没有可用的数据直接返回,而不是阻塞在这里,直到数据变得可读取。在数据变得可读取之前该线程是可以继续处理其他任务的。
非阻塞写:如某个线程发送写请求,需要写一些数据到通道中,但不需要等到将所有数据都完全写入,该线程可以同时做其他任务。
线程通常将非阻塞的IO的空闲时间用来执行其他通道的IO任务,所以一个单独的线程可以管理多个输入和输出通道。

Channel

通道:channel 是在rt.jar java.util.nio 包下定义的,表示io源与目标打开的链接。
通道不能直接传输数据只能配合缓冲区使用。
通道类似于流 ,但是通道是双向的,即可以将通道指向的目标源数据读入到缓冲区,也可以将缓冲区数据写入到链接通道的目标源。通道好比是铁路,缓冲区为火车,火车载人,通过铁路来运输。

Buffer

缓冲区是存储数据的数组
重要属性
1 capacity:缓冲区容量大小,一旦创建不可改变
2 limit:缓冲区可用数据大小,也就是缓冲区最后一个可操作数据的下标,该下标之后的缓冲区数据不可操作。小于等于capacity
3 position:当前操作的位置。小于等于limit
4 mark:上一次标记的索引位置

Selector

选择器 ,它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。
使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。

1Selector selector = Selector.open(); 2channel.configureBlocking(false); 3SelectionKey key = channel.register(selector, Selectionkey.OP_READ); 4channel.configureBlocking(false);

将通道设置为非阻塞式,FileChannel 是阻塞式的不能使用选择器,SocketChannel 网络套接字的通道可以设置为非阻塞式。

register方法的第二个参数是监听事件的类型。选择器可以监听以下四种类型的事件
Connect :链接就 SelectionKey.OP_CONNECT
Accept:接收就绪 SelectionKey.OP_ACCEPT
Read:读就绪 SelectionKey.OP_READ
Write:写就绪 SelectionKey.OP_WRITE

可以通过以下方法来确定以上事件是否准备就绪,它们都会返回一个布尔类型:
链接就绪:selectionKey.isConnectable();
接收就绪:selectionKey.isAcceptable();
读就绪:selectionKey.isReadable();
写就绪:selectionKey.isWritable();

1Set selectedKeys =selector.selectedKeys(); 2 3Iterator keyIterator = selectedKeys.iterator(); 4 5while(keyIterator.hasNext()) { 6 SelectionKey key = keyIterator.next(); 7 if(key.isAcceptable()) { 8 // a connection was accepted by a ServerSocketChannel. 9 } else if (key.isConnectable()) { 10 // a connection was established with a remote server. 11 } else if (key.isReadable()) { 12 // a channel is ready for reading 13 } else if (key.isWritable()) { 14 // a channel is ready for writing 15 } 16 keyIterator.remove(); 17}

直接缓冲区与非直接缓冲区

非直接缓冲区

客户端向服务端发送数据,先将数据发送到虚拟机中用户地址中空间的缓存中,然后用户地址空间将数据复制到系统内核地址空间的缓存中,内核地址空间将数据写入到系统的物理磁盘中

直接缓冲区

直接缓冲区省去了用户地址空间缓存到内核地址空间缓存的复制过程,用物理内存映射文件来代替,直接将数据存入到物理内存中,然后在将数据存入到物理磁盘中。
可以通过Buffer.allocateDirect 方法来创建直接缓冲区。

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

IO模型(BIO,NIO,AIO)及其区别

BIO:同步阻塞IONIO:同步非阻塞IOAIO:异步非阻塞IO先弄清楚同步、异步,阻塞、非阻塞概念。io操作分为两部分,发起io请求,和io数据读写。阻塞、非阻塞主要是针对线程发起io请求后,是否立即返回来定义的,立即返回称为非阻塞io,否则称为阻塞io。同步、异步主要针对io数据读写来定义的,读写数据过程中不阻塞线程称为异步io

JAVA中的BIO、NIO和AIO

Java中的IO方式主要分为3种:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。BIO同步阻塞模式。在JDK1.4以前,使用Java建立网络连接时,只能采用BIO方式,在服务器端启动一个ServerSocket,然后使用accept等待客户端请求,对于每一个请求,使用一个线程来进行处理用户请求。线程的大部分时间都在等待请求的

Java NIO和IO的区别

IO               NIO面向流           面向缓冲阻塞IO           非阻塞IO无               选择器面向流与面向缓冲JavaNIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。JavaIO面向流意味着每次从流中

Java.NIO编程一览笔录

Java标准IO与JavaNIO的简单差异示意: Java标准IOJavaNIOAPI调用简单复杂底层实现面向流(stream),单向面向通道(channel),释放CPU、内存压力成效同步阻塞同步非阻塞数据窥视阻塞读取,要么足够,要么没有使用缓冲区(Buffer),读数据时需要检查是否

NIO阻塞与非阻塞IO

一、使用NIO完成网络通信的三个核心1、通道(Channel):负责连接java.nio.channels.Channel接口|–SelectableChannel|–SocketChannel|–ServerChannel|–DatagramChannel|–Pipe.SinkChannel|–Pipe