首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

NIO非阻塞网络编程三大核心理念

本次开始NIO网络编程,之前已经说过BIO,对于阻塞IO里面的问题一定有了清晰的认识,在JDK1.4版本后,提供了新的JAVA IO操作非阻塞API,用意替换JAVA IO 和JAVA NetWorking相关的API。NIO其实有个名称叫new IO。

(一)NIO

介绍

java.nio全称java non-blocking IO(实际上是 new io),是指JDK 1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。

三大核心组件

高性能网络编程的基础组件,Buffer缓存区、Channel 通道、Selector 选择器。

(二) Buffer缓存区

介绍

缓存区本质上是一个可以写入数据的内存块(类似数组),然后可以再次读取。此内存块包含在NIO Buffer 对象中,该对象提供了一组方法,可以更轻松地使用内存块。

相比较直接对数组的操作。Buffer API 更加容易操作和管理。

使用Buffer进行数据写入与读取,需要进行如下四个步骤

将数据写入缓冲区。

调用buffer.flip(),转换为读取模式。

缓冲区读取数据。

调用buffer.clear() 或 buffer.compact() 消除缓冲区

Buffer工作原理

BUffer三个重要属性,通过完成了数组的封装。

1.capacity 容量:作为一个内存块,Buffer具有一定的固定大小,也称为【容量】。

2.position 位置:写入模式时代表写数据的位置。读取模式时代表读取数据的位置。

3.limit 限制:写入模式,限制等于buffer的容量,读取模式下,limit等于写入的数据量。

源码

ByteBuffer 内存类型

ByteBuffer 为性能关键型代码提供了直接内存(direct堆外)和非直接内存(heap堆)两种实现,堆外内存获取的方式

好处

进行网络IO 或者 文件IO时比heapBuffer 少一次拷贝,(file/socket —— OS memory —— jvm heap )GC会移动对象内存,在写file 或 socket的过程中,JVM的实现中,会先把数据复制到堆外,在进行写入。

GC范围之外,降低GC压力,但实现了自动管理。DirectByteBuffer 中 有一个Cleaner 对象(PhantomReference) ,Cleaner被GC前会执行clean 方法,触发DirectByteBuffer 中定义Deallocator

建议

性能确实可观的时候才去使用,分配给大型,长寿命(网络传输,文件读写场景)

通过虚拟机参数MaxDirectMemorySize限制大小,防止耗尽整个机器的内存,在JVM之外的内存无法监控。

(三)Channel 通道

介绍

Channel的API 涵盖了UDP、TCP网络和文件IO,FileChannel,DatagramChannel,SocketChannel,ServerSocketChannel。

和标准IO Stream操作的区别

在一个通道内进行读取和写入stream通常是单向的(input 或 output),可以非堵塞读取和写入通道,通道中读取或写入缓冲区。

SocketChannel

SocketChannel用于建立TCP网络连接,类似java.net.Socket。有两种创建socketChannel形式

1.客户端主动发起和服务器的连接

2.服务器获取的新连接

write写

在尚未写入任何内容时可能就返回了。需要在循环中调用write()

read读

read() 方法可能直接返回而根本不读取任何数据,根据返回的int值判断读取了多少字节。

ServerSocketChannel

ServerSocketChannel 可能监听新建立的TCP连接通道,类似ServerSocket。

ServerSocketChannel.accepta()

如果该通道处于飞度赛模式,那么如何没有挂起的连接,该方法将立即返回null。必须检查返回的SocketChannel是否为null。

源码

(四)Select选择器

介绍

Selector 是一个Java NIO 组件,可以检查一个或多个NIO通道,并确定哪些通道已准备好进行读取或写入,实现单个线程可以管理多个通道,从而管理或多个网络连接。

selector 监听多个 channel的不同事件

Connect 连接(SelectionKey.OP_CONNECT)

Accept 准备就绪(OP_ACCEPT)

Read 读取(OP_READ)

Write 写入(OP_WRITE)

selector 选择器

一个线程处理多个通道的核心概念理解:事件驱动机制。

非堵塞的网络通道下,开发者通过Selector注册对于通道感兴趣的事件类型,线程通过监听事件来触发响应的代码执行(最底层hi操作系统的多路复用机制)

源码

NIO 和 BIO 的区别

NIO Reactor的方式

PS:NIO为开发者提供了功能丰富及强大的IO处理API,但是在应用开发的过程中,直接使用JDK提供的API,比较繁琐,而且要想将性能进行提升,光有NIO还是不够的,还需要将多线程技术与之结合起来。因为网络编程本身的复杂性,以及JDK API开发的使用难度较高,所以开源社区中,涌出来很多的JDK NIO进行封装了,增强后的网络编程框架,例如:Netty、Mina等。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201125A0DFUR00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券