NIO相比BIO的优势
NIO(Non-blocking I/O , 在JAVA领域 , 也称为New I/O) , 是一种同步非阻塞的I/O模型 , 也是I/O多路复用的基础 , 已经被越来越多地应用到大型应用服务器 , 成为解决高并发与大量连接、I/O处理问题的有效方式 。
文章插图
面向流与面向缓冲
Java NIO和BIO之间第一个最大的区别是 , BIO是面向流的 , NIO是面向缓冲区的 。JavaIO面向流意味着每次从流中读一个或多个字节 , 直至读取所有字节 , 它们没有被缓存在任何地方 。此外 , 它不能前后移动流中的数据 。如果需要前后移动从流中读取的数据 , 需要先将它缓存到一个缓冲区 。Java NIO的缓冲读取方法略有不同 。数据读取到一个缓冲区 , 需要时可在缓冲区中前后移动 。这就增加了处理过程中的灵活性 。但是 , 还需要检查是否该缓冲区中包含所有需要处理的数据 。而且 , 需确保当更多的数据读入缓冲区时 , 不要覆盖缓冲区里尚未处理的数据 。
阻塞IO与非阻塞IO
Java IO的各种流是阻塞的 。这意味着 , 当一个线程调用read() 或write()时 , 该线程被阻塞 , 直到有数据被读取或者数据写入 。该线程在阻塞期间不能做其他事情 。而Java NIO的非阻塞模式 , 如果通道没有东西可读 , 或不可写 , 读写函数马上返回 , 而不会阻塞 , 这个线程可以去做别的事情 。线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作 , 所以一个单独的线程可以管理多个输入和输出通道(channel) , 即IO多路复用的原理 。
零拷贝
在传统的文件IO操作中 , 我们都是调用操作系统提供的底层标准IO系统调用函数read()、write() , 此时调用此函数的进程(在JAVA中即java进程)由当前的用户态切换到内核态 , 然后OS的内核代码负责将相应的文件数据读取到内核的IO缓冲区 , 然后再把数据从内核IO缓冲区拷贝到进程的私有地址空间中去 , 这样便完成了一次IO操作 。
文章插图
而NIO的零拷贝与传统的文件IO操作最大的不同之处就在于它虽然也是要从磁盘读取数据 , 但是它并不需要将数据读取到OS内核缓冲区 , 而是直接将进程的用户私有地址空间中的一部分区域与文件对象建立起映射关系 , 这样直接从内存中读写文件 , 速度大幅度提升 。
文章插图
详细的解析 , 之后会有单独的博客进行讲解
NIO的核心部分
Java NIO主要由以下三个核心部分组成:
- Channel
- Buffer
- Selector
基本上 , 所有的IO在NIO中都从一个Channel开始 。数据可以从Channel读到Buffer中 , 也可以从Buffer写到Channel中 。这里有个图示:
文章插图
Channel和Buffer有好几种类型 。下面是Java NIO中的一些主要Channel的实现:
- FileChannel(file)
- DatagramChannel(UDP)
- SocketChannel(TCP)
- ServerSocketChannel(TCP)
文章插图
最后两个channel的关系 。通过 ServerSocketChannel.accept() 方法监听新进来的连接 。当 accept()方法返回的时候,它返回一个包含新进来的连接的 SocketChannel 。因此, accept()方法会一直阻塞到有新连接到达 。通常不会仅仅只监听一个连接,在while循环中调用 accept()方法.
//打开 ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
while(true){
SocketChannel socketChannel = serverSocketChannel.accept();
//do something with socketChannel...
}
//关闭ServerSocketChannel
serverSocketChannel.close();
Buffer
缓冲区本质上是一块可以写入数据 , 然后可以从中读取数据的内存 。这块内存被包装成NIO Buffer对象 , 并提供了一组方法 , 用来方便的访问该块内存 。
推荐阅读
- 各行的祖师爷是谁 自古以来各行各业的祖师爷
- 控制器|龙吟师傅教你布局办公室来催桃花
- 民主小学教师教育随笔 小学教师教学随笔
- 阴阳师|阴阳师:钓鱼系统出现?外服又玩梗,玩家希望愚人节笑话成真
- 祁门红茶馨香世界茶叶香气大师百岁华诞
- LOL5.18金属大师改动 莫德凯撒最新出装加点 金属大师加点
- 架构师分享:RocksDB使用技巧之分布式存储扩容演进
- 电商网站架构探索之SOA
- 浅谈Javaweb经典三层架构和MVC框架模式
- 华为达芬奇架构和arm架构有什么区别?