NIO Selector简介
1.Selector和Channel关系
Selector一般称为选择器,也叫多路复用器,NIO的核心组件,用于检查一个或多个Channel的状态是否处于可读、可写的状态。

2.可选择通道
(1)不是所有的channel都能被selector复用,就是要看channel是否继承SelectableChannel,如果继承了就是可以复用。例如:FileChannel是不能被selector复用的。
(2)一个通道可以被注册到多个选择骑上,但每个选择器只能被注册一次。在注册的时候,需要指定通道那些操作是选择器感兴趣的。

3.Channel注册到Selector
- Channel.register(Selector sel, int ops) 方法:将一个通道注册到一个选择器上。第一个参数,指定通道要注册的选择器。第二个参数指定选择器需要查询的通道操作。
- 可以供选择器查询的通道操作,包括如下四种(可以通过位或操作符表示多种操作类型感兴趣):
(1)可读SelectionKey.OP_READ
(2)可写SelectionKey.OP_WRITE
(3)连接SelectionKey.OP_CONNECT
(4)接收SelectionKey.OP_ACCEPT
3.1 选择键(SelectionKey)
(1)Channel注册后,一旦通道处于某种就绪的状态,就可以被选择器查询到。
(2)Selector不断查询Channel中操作的就绪状态,并挑选感兴趣的操作就绪状态,并放入选择键集合。
(3)一个选择键包含了特定通道域特定选择器之间的注册关系。
NIO就是根据对应的选择键,进行不同的业务逻辑处理。
3.2 Selector的使用方法
(1) Channel必须处于非阻塞模式下,否则会抛出IllegalBlockingModeException
(2)一个通道不一定支持所有的四种操作,比如ServerSocketChannel支持Accept操作,SocketChannel则不支持。可通过validOps()获取支持的操作集合。
- Selector的创建
// 创建SelectorSelector sl = Selector.open();// 创建通道ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 非阻塞serverSocketChannel.configureBlocking(false);// 绑定连接serverSocketChannel.bind(new InetSocketAddress(9999));//将通道注册到选择器上serverSocketChannel.register(sl, SelectionKey.OP_ACCEPT);System.out.println(serverSocketChannel.validOps());
2.轮询查询就绪操作
//查询已经就绪通道操作Set<SelectionKey> selectionKeys = sl.selectedKeys(); // 遍历集合Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey next = iterator.next();// 判断key的就绪状态操作if (next.isAcceptable()) {} else if (next.isConnectable()) {} else if (next.isReadable()) {} else {}iterator.remove();}
4 实验案例
import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;
import org.junit.jupiter.api.Test;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;/*** @Des* @Date*/
public class Demo2 {@Test// 客户端代码public void client() throws IOException {// 获取通道,绑定主机和端口号SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));// 切换为非阻塞模式socketChannel.configureBlocking(false);// 创建bufferByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 写入bufferbyteBuffer.put(new Date().toString().getBytes());// 读写模式转换byteBuffer.flip();// channel写入数据socketChannel.write(byteBuffer);// 清空bufferbyteBuffer.clear();}@Test// 客户端代码public void Serverdemo() throws IOException {// 获取通道,绑定主机和端口号ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 非阻塞serverSocketChannel.configureBlocking(false);// 创建bufferByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 绑定连接serverSocketChannel.bind(new InetSocketAddress(8080));// 获取selector选择器Selector sl = Selector.open();// 通道注册到选择器,并进行监听serverSocketChannel.register(sl, SelectionKey.OP_ACCEPT );// 选择器进行轮询while (sl.select() > 0) {Set<SelectionKey> selectionKeys = sl.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey next = iterator.next();// 判断何种类型操作if (next.isAcceptable()) {// 获取连接SocketChannel accpet = serverSocketChannel.accept();//切换非阻塞模式accpet.configureBlocking(false);// 注册accpet.register(sl, SelectionKey.OP_READ);} else if (next.isReadable()) {SocketChannel socketChannel = (SocketChannel) next.channel();// 读取数据int length = 0;while ((length = socketChannel.read(byteBuffer)) > 0) {byteBuffer.flip();System.out.println("receiver" + new String(byteBuffer.array(), 0, length));}}}iterator.remove();}}}相关文章:
NIO Selector简介
1.Selector和Channel关系 Selector一般称为选择器,也叫多路复用器,NIO的核心组件,用于检查一个或多个Channel的状态是否处于可读、可写的状态。 2.可选择通道 (1)不是所有的channel都能被selector复用,…...
2023-12蓝桥杯STEMA考试 C++ 中高级试卷解析
蓝桥杯STEMA考试 C++ 中高级试卷(12月) 一、选择题 第一题 定义字符串 string a = "Hello C++",下列选项可以获取到字符 C 的是(B)。 A、a[7] B、a[6] C、a[5] D、a[4] 第二题 下列选项中数值与其它项不同的是( C)。 A、 B、 C、 D、 第三题 定义变量 int i =…...
设计模式——2_1 命令(Command)
文章目录 定义图纸一个例子:空调和他的遥控器只有控制面板的空调遥控器可以撤销的操作 碎碎念命令和Runnable命令和事务 定义 把请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持…...
HP数组面试题
PHP数组面试题 问题: 如何创建一个空数组和一个带有初始值的数组? 答案: 创建空数组:可以使用array()函数或空数组语法[]来创建一个空数组,例如$arr array();或$arr [];。创建带有初始值的数组:可以在创建…...
机器学习5-线性回归之损失函数
在线性回归中,我们通常使用最小二乘法(Ordinary Least Squares, OLS)来求解损失函数。线性回归的目标是找到一条直线,使得预测值与实际值的平方差最小化。 假设有数据集 其中 是输入特征, 是对应的输出。 线性回归的…...
vulhub中Adminer ElasticSearch 和 ClickHouse 错误页面SSRF漏洞复现(CVE-2021-21311)
Adminer是一个PHP编写的开源数据库管理工具,支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其4.0.0到4.7.9版本之间,连接 ElasticSearch 和 ClickHouse 数据库时存在一处服务端请求伪造漏洞(…...
浅谈Zookeeper及windows下详细安装步骤
1. Zookeeper介绍 1.1 分布式系统面临的问题 分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。 面临的问题:系统每个节点之间信息同步及共享 以一个小团队为例,面临的问题 通过网络进行信息…...
vite, vue3, vue-router, vuex, ES6学习日记
学习使用vitevue3的所遇问题总结(2024年2月1日) 组件中使用<script>标签忘记加 setup 这会导致Navbar 没有暴露出来,导致使用不了,出现以下报错 这是因为,如果不用setup,就得使用 export default…...
25考研|660/880/1000/1800全年带刷计划
作为一个参加过两次研究生考试的老学姐,我觉得考研数学的难度完全取决于你自己 我自己就是一个很好的例子 21年数学题目是公认的简单,那一年考130的很多,但是我那一年只考了87分。但是22年又都说是有史以来最难的一年,和20年的难度…...
Mybatis基础教程及使用细节
本篇主要对Mybatis基础使用进行总结,包括Mybatis的基础操作,使用注解进行增删改查的练习;详细介绍xml映射文件配置过程并且使用xml映射文件进行动态sql语句进行条件查询;为了简化java开发提高效率,介绍一下依赖&#x…...
10 分钟在K8s 中部署轻量级日志系统 Loki
转载至我的博客 https://www.infrastack.cn ,公众号:架构成长指南 Loki 是什么? Loki是由Grafana Labs开源的一个水平可扩展、高可用性,多租户的日志聚合系统的日志聚合系统。它的设计初衷是为了解决在大规模分布式系统中&#x…...
图像处理python基础
array 读取图片 tensor 模型预测 一般过程:读取数据np->tensor->model->result->np->画图 shape确保图像输入输出尺寸正确 读取图片 将在GPU上运行的tensor类型转变成在CPU上运行的np类型 三类计算机视觉任务的输入: 分类࿱…...
基于WordPress开发微信小程序2:决定开发一个wordpress主题
上一篇:基于WordPress开发微信小程序1:搭建Wordpress-CSDN博客 很快发现一个问题,如果使用别人的主题模板,多多少少存在麻烦,所以一咬牙,决定自己开发一个主题模板,并且开源在gitee上ÿ…...
[Python] 什么是网格搜索以及scikit-learn中GridSearch类的介绍和使用案例?
什么是网格搜索? 网格搜索是一种参数调优的方法,它可以帮助找到最佳的模型参数。在网格搜索中,我们先指定参数的候选值范围,然后枚举所有可能的参数组合,计算每个模型的性能指标(比如准确率、精确率等&…...
Linux-正则表达式
1.正则表达式的定义: 正则表达式通常用于判断语句中,使用字符串描述、匹配一系列符合某个规则的字符串。 正则表达式是由普通字符与元字符组成。 普通字符包括小写字母、数字、标点符号及一些其他符号。元字符是指在正则表达式中具有特殊意义的专用字符&…...
Java基础学习:System类和Static方法的实际使用
一、System类 1.在程序开发中,我们需要对这个运行的结果进行检验跟我们预判的结果是否一致,就会用到打印结果在控制台中显示出来使用到了System类。System类定义了一些和系统相关的属性和方法,它的属性和方法都是属于静态的,想使用…...
线性代数------矩阵的运算和逆矩阵
矩阵VS行列式 矩阵是一个数表,而行列式是一个具体的数; 矩阵是使用大写字母表示,行列式是使用类似绝对值的两个竖杠; 矩阵的行数可以不等于列数,但是行列式的行数等于列数; 1.矩阵的数乘就是矩阵的每个…...
Flutter 开发3:创建第一个Flutter应用
Step 1: 安装Flutter 1.1 下载Flutter SDK 首先,你需要访问Flutter官方网站下载最新的Flutter SDK。选择适合你操作系统的安装包。 $ cd ~/development $ unzip ~/Downloads/flutter_macos_2.2.3-stable.zip1.2 更新环境变量 接下来,你需要将Flutter…...
Linux中断下半部分:软中断,tasklet和工作队列
为什么要有下半部分 中断会打断其他程序,为了打断其他程序时间短,就需要中断处理程序快。执行中断处理程序后,相同中断不会触发,甚至所有中断都不能触发(设置IRQF_DISABLED,其他硬件与操作系统无法通信)中…...
Flink CEP实现10秒内连续登录失败用户分析
1、什么是CEP? Flink CEP即 Flink Complex Event Processing,是基于DataStream流式数据提供的一套复杂事件处理编程模型。你可以把他理解为基于无界流的一套正则匹配模型,即对于无界流中的各种数据(称为事件),提供一种组合匹配的…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
