Netty开篇——NIO章上(三)

Java NIO基本介绍

  1. java non-blocking I/O 称为NIO(也叫New IO)。JDK4开始提供,同步非阻塞
  2. 相关内容在 java.nio 包及子包下,对java.io 包中的很多类进行改写。
  3. 三大核心: Channel(通道),Buffer(缓冲区),Selector(选择器)
  4. NIO是面向缓冲区或者面向块编程。数据读取到一个它后处理的缓冲区,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络
  5. NIO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据可以读取之前,该线程可以继续做其他的事情。
  6. 通俗理解: NIO 是可以做到用一个线程来处理多个操作。假设有 10000 个请求过来,根据实际情况,可以分配50 或者 100 个线程来处理。不像之前的阻塞IO 那样,非得分配 10000 个。
  7. HTTP2.0 使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比 HTTP1.1 大了好几个数量级
  8. 基本案例

NIO 和 BIO 的比较

  1. BIO以流的方式处理数据,而NIO以块的方式处理数据,I/O块的效率比I/O流高很多
  2. BIO 是阻塞的,NIO则是非阻塞的
  3. BIO 基于字节流和字符流进行操作,而NIO基于Channel(通道)和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector 选择器用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道

Selector、Channel 和 Buffer 的关系图

  1. 每个channel都会对应一个Buffer
  2. 一个Selector对应一个线程
  3. 多个channel会注册到其selector
  4. Selector会根据不同的Event,在各个Channel上切换
  5. channel 是双向的,可以返回底层操作系统的情况,比如Linux,底层的操作系统通道就是双向的.
  6. Buffer是一个内存块,底层是一个数组
  7. 数据的读取写入是通过 Buffer这个和BIO有所区别,BIO 中要么是输入流,或者是输出流,不能双向,但是NIO的Buffer是可以读也可以写,需要flip()切换

 

缓冲区(Buffer)

  1. Buffer本质上是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以更轻松地使用内存块,Buffer对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况。Channel 读写的数据都必须经由Buffer
  2. Buffer是父类、抽象类,类的层级关系图
  3. 常用Buffer子类

    • ByteBuffer 存储字节数据到缓冲区
    • shortBuffer 存储字符串数据到缓冲区
    • CharBuffer 存储字符数据到缓冲区
    • IntBuffer 存储整数数据到缓冲区
    • LongBuffer 存储长整型教据到缓冲区
    • DoubleBuffer 存储小数到缓冲区
    • FloatBuffer 存储小数到缓冲区
  4. 这些Buffer都把数据存于自己类型的数组

  5. Buffer类的四个属性:
    • Capacity:容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变
    • Limit:表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。且极限是可以修改的
    • Position:位置,下一个要被读写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写做准备
    • Mark:标记

Buffer类相关方法

public abstract class Buffer{
//JDK1.4时,引入的api
public final int capacity()//返回此缓冲区的容量
public final int position()//返回此缓冲区的位置
public final Buffer position(int newPositio)//设置此缓冲区的位置
public final int limit()//返回此缓冲区的限制
public final Buffer limit(int newLimit)//设置此缓冲区的限制
public final Buffer mark()//在此缓冲区的位置设置标记
public final Buffer reset()//将此缓冲区的位置重置为以前标记的位置
public final Buffer clear()//清除此缓冲区,即将各个标记恢复到初始状态,但是数据并没有真正擦除,
public final Buffer flip()//反转此缓冲区
public final Buffer rewind()//重绕此缓冲区
public final int remaining()//返回当前位置与限制之间的元素数
public final boolean hasRemaining()//告知在当前位置和限制之间是否有元素
public abstract boolean isReadOnly()://告知此缓冲区是否为只读缓冲区
//JDK1.6时引入的api
public abstract boolean hasArray();//告知此缓冲区是否具有可访问的底层实现数组
public abstract Object array();//返回此缓冲区的底层实现数组
public abstract int arrayOffset();/返回此缓冲区的底层实现数组中第一个缓冲区元素的偏移量
public abstract boolean is Direct();//告知此缓冲区是否为直接缓冲区
}

ByteBuffer

  1. 除了boolean,其他基本类型都有一个Buffer类型与之相对应,最常用的自然是 ByteBuffer 类(二进制数据),该类的主要方法如下:
public abstract class ByteBuffer(
//缓冲区创建相关api
public static ByteBuffer allocateDirect(int capacity)//创建直接缓冲区
public static ByteBuffer allocate(int capacity)//设置缓冲区的初始容量
public static ByteBuffer wrap(byte[] array)//把一个数组放到缓冲区中使用
//构造初始化位置offset和上界length的缓冲区
public static ByteBuffer wrap(byte[] array,int offset, int length)
//缓存区存取相关API
public abstract byte get()//从当前位置position上get,get之后,position会自动+1 
public abstract byte get(int index);//从绝对位置get
public abstract ByteBuffer put(byte b);//从当前位置上添加,put之后,position会自动+1 
public abstract ByteBuffer put(int index,byte b);//从绝对位置上put

关于Buffer的注意事项和细节

  1. ByteBuffer支持类型化的put和get,数据类型必须保持一致,否则可能有 BufferUnderflowException 异常。
  2. Buffer支持转换为只读buffer,调用asReadOnlyBuffer()
  3. NIO还提供了MappedByteBuffer,可以让文件直接在内存(堆外内存) 中进行修改,而如何同步到文件由NIO来完成.
  4. NIO还支持通过多个Buffer(buffer数组)完成读写操作即 Scattering(分散)和 Gathering(合并)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos7.9服务器编译安装Nginx1.24.0和php8.3

Centos7.9服务器编译安装Nginx1.24.0和php8.3 服务器nginx原版本有安全漏洞,需要升级,由于原始是yum源安装,通过yum直接升级,无法正常升级完成,故而需要卸载yum源,重新编译安装。 1、查看原来nginx版本,ps查看原来nginx进程,运行状态: ps aux | grep nginx ​ root …

【HuggingFace Transformer库学习笔记】基础组件学习:Evaluate

基础组件学习——Evaluate Evaluate使用指南 查看支持的评估函数 # include_community:是否添加社区实现的部分 # with_details:是否展示更多细节 evaluate.list_evaluation_modules(include_communityFalse, with_detailsTrue)加载评估函数 accuracy…

RK3568驱动指南|第十二篇 GPIO子系统-第135章 GPIO子系统与pinctrl子系统相结合实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

解决ELK日志收集中Logstash报错的关键步

ElK执行日志收集的时候logstash报错: Failed to execute action {:action>LogStash::PipelineAction::Create/pipeline_id:main, :exception>“LogStash::ConfigurationError”, :message>“Expected one of [^\r\n], “\r”, “\n” at line 88, column 4…

ChromeDriver 添加到系统PATH

在软件测试和自动化脚本中,ChromeDriver是一个不可或缺的工具。为了方便使用,将其添加到系统PATH中是一个明智的选择。以下是在Windows、macOS或Linux上完成此任务的详细步骤。 在 Windows 上: 下载并保存 ChromeDriver: 访问Chro…

openEuler安装Docker艰辛路程

文章目录 安装docker测试docker关于windows docker拉取镜像查看所有镜像删除镜像删除不在运行的进程强制删除正在运行的进程 启动docker容器服务-d测试 停止docker容器服务查看docker启动进程更新容器(没有自启动功能,更新为自启动)docker端口映射进入容器修改内容退…

Unity AssetBundles资源管理和热更新

项目中的做法,在项目中一般会把资源按照文件目录去划分资源,以文件路径的名字作为AB的名字,一般都是把资源的这些放到预处理中。 一般会分为几个类型,比如把单个文件夹下的每个资源进行打bundle,把单个文件夹下的所有资…

新手练习项目 5:简易计算器(C++)

名人说:莫听穿林打叶声,何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder) 目录 一、效果图二、代码(带注释)三、说明 一、效果图 二、代码(带…

HTML--图片

HTML中使用 img标签来显示一张图片 它有三个属性&#xff1a; src alt tiltle src属性&#xff1a; 图片路径建议为相对路径&#xff0c;以免文件移动造成无法正常工作 用法&#xff1a; <img src"图片路径和名字"><!DOCTYPE html> <html> <…

QWebEngineView类方法、属性、信号与槽汇总

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 使用示例📝 方法📝 属性📝 信号(Signals)📝 槽(Slots)⚓️ 相关链接 ⚓️📖 介绍 📖 QWebEngineView 是 Qt 提供的一个用于呈现 Web 内容的类,基于 Google 的 Chromium 浏览器引擎。它提供了对现…

Mac M1 Parallels CentOS7.9 Install Jenkins

官网: https://www.jenkins.io/ 一、Install & Check Java Env Oracle官网下载Java: https://www.oracle.com/cn/ # 拷贝到Jenkins服务器 scp Downloads/jdk-8u391-linux-aarch64.tar.gz root10.211.55.34:~# 解压 mkdir -p /opt/java && tar -zxvf jdk-8u391-li…

电脑上不安装Oracle,但是虚拟机装了Oracle,怎么连接到虚拟机里的Oracle数据库呢?

1、准备工作 1.1、确定数据库版本信息 注&#xff1a;如果知道数据库的版本信息&#xff0c;这个步骤可以跳过。 比较简单的方法&#xff0c;直接看数据库的安装位置&#xff0c;也就是数字&#xff08;但是这个方法确定就是&#xff0c;不好确定是多少位的数据库&#xff09;…

使用pandas按照商品和下单人统计下单数据

目录 一&#xff1a;需求描述 二&#xff1a;代码实现 三&#xff1a;注意事项 一&#xff1a;需求描述 最近运营那边给到一个excel表格&#xff0c;是一个小程序用户的下单数据&#xff0c;要以商品为维度&#xff0c;统计用户下单情况&#xff0c;主要是下单的商品总金额&…

CMake+大漠插件的应用开发——处理dm.dll,免注册调用大漠插件

文章目录 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件简介环境项目结构配置编译环境编码-直接调用 dll编码-生成tlh文件&#xff0c;便于提示 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件 简介 网上有一种使用方式是&am…

Navicat连接不上虚拟机中linux的dockers创建的mysql

说明&#xff1a;这个问题可能只是我的个人问题&#xff0c;记录一下吧。当发现这个问题的时候&#xff0c;去网上搜素了一下&#xff0c;搜到的文章基本上都是通过在mysql中设置允许远程访问解决的&#xff0c;然后我也跟着尝试了一下&#xff0c;问题并没有解决。后面就乱七八…

allegro PCB设计心得笔记(二) PCB板框设计心得

Cadence Allegro软件设计PCB板框时&#xff0c;使用Add -> line&#xff0c;在Option选择Board Geometry/Outline&#xff0c;根据PCB需要输入对应坐标&#xff0c;设计好板框。 使用Z-Copy命令设计Route Keepin和Package Keepin时&#xff0c;需要先使用使用Shape -> Co…

【Python】Python语言 3小时速通(有C语言基础版)

python从入门到实践 变量 message"hello world"并不需要指出变量类型 方法 tittle()#以首字母大写的形式输出单词upper()#全部大写输出lower()#全部小写输出存储数据时经常使用lower&#xff0c;因为无法确保数据是大写还是小写 rstrip()#输出删除字符串尾部多余…

YOLOv5涨点改进:多层次特征融合(SDI),小目标涨点明显,| UNet v2,比UNet显存占用更少、参数更少

💡💡💡本文全网独家改进:多层次特征融合(SDI),能够显著提升不同尺度和小目标的识别率 💡💡💡在YOLOv5中如何使用 1)iAFF加入Neck替代Concat; 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于Yolov5、Yolov7、Yolov8等各个Yolo系列,专栏文…

RabbitMQ 的基本概念

一 MQ 的基本概念 1 MQ概述 MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。消息队列就是所谓的存放消息的队列。 消息队列解决的不是存放消息的队列的⽬的&#xff0c;解决的是通信问…

三、GCC编译:链接

代码准备 main.c extern int shared; extern void func(int *a, int *b); int main(){int a 100;func(&a, &shared);return 0; }func.c int shared 1; int tmp 0; void func(int *a, int *b){tmp *a;*a *b;*b tmp; }静态链接 编译 gcc -static -fno-stack-p…