NIO
全称New IO
或Non Blocking IO(非阻塞IO)
NIO与IO的区别
IO | NIO |
---|---|
面向流(Stream Oriented) | 面向缓冲区(Buffer Oriented) |
阻塞IO(Blocking IO) | 非阻塞IO(Non Blocking IO) |
无 | 选择器(Selectors) |
Channel
通道,相当于火车的铁轨。
Buffer
缓冲区,NIO用于数据传输的载体。
不同的基本数据类型有对应的缓冲区(boolean除外)
最常用的还是ByteBuffer
主要方法:
allocate()
初始化缓存区大小至JVM内存allocateDirect()
初始化缓存区大小至操作系统的物理内存capacity()
缓存区大小容量position()
读写操作的指针位置limit()
操作的边界值put()
将数据放入buffer中get()
获取buffer中的数据flip()
切换成读取模式rewind()
将position设为0clear()
将position设为0,limit设为capacity,之前写入的数据“被遗忘”compact()
将所有未读数据拷贝至Buffer数字的前面,limit同样设为capacitymark()
标记当前的position()位置reset()
将position恢复到mark()标记的位置
allocate()与allocateDirect()的优缺点
- 直接在操作系统内存上进行操作,大大避免了从直接OS的内存中复制数据到JVM的内存中,或从JVM内存中复制到OS内存中
- 直接内存的分配与取消分配通常都是高于非直接内存的,建议在易受操作系统IO操作影响的大型,持久的缓存区
网络IO
NIO非阻塞网络IO与传统网络IO的区别:
- 传统网络IO,是直接在Client与Server之间建立起IO连接,若Client端建立连接后,未及时发送数据,则Server端阻塞等待,若请求的并发增大,则阻塞的线程数增多,则Server端的CPU资源被占用;
- NIO,通过选择器(Selectors),监听Client与Cient建立起来的Channel,当Client的Channel准备就绪后(Buffer数据已经准备好即将发送),选择器再通过多线程,将IO请求发送至Server端,使得Server端多线程处理IO不会阻塞,更好地利用了Server端的CPU资源。
基于非阻塞IO的单向“聊天室”实例
package pro.eddie.demo;
import org.junit.Test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util