高并发IO底层原理浅析(四)

Java NIO中的Selector(选择器)是一个用于检测多个非阻塞通道(Channel)是否准备就绪进行读写操作的关键组件,它实现了I/O多路复用技术。在单个线程中,Selector可以监听和管理多个Channel上的事件,这样就极大地提高了服务器端处理大量并发连接的效率。

原理: Selector基于操作系统提供的I/O复用API实现,例如Linux下的epoll或Windows下的IOCP等,它可以同时监控多个Channel,当任何一个Channel上有新的可读、可写或有连接建立等事件发生时,Selector会将这些事件通知给应用程序。

使用方法举例: 以下是一个简化的示例,展示如何创建一个Selector并注册Channel以及轮询待处理的事件:

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.Iterator;public class SelectorExample {public static void main(String[] args) throws IOException {// 创建SelectorSelector selector = Selector.open();// 打开ServerSocketChannel,并设置为非阻塞模式ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);serverSocketChannel.socket().bind(new InetSocketAddress(8080));// 将ServerSocketChannel注册到Selector上,监听接受新连接事件(OP_ACCEPT)SelectionKey key = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 轮询等待感兴趣的事件发生if (selector.select() > 0) { // 如果至少有一个事件发生Iterator<SelectionKey> keysIterator = selector.selectedKeys().iterator();while (keysIterator.hasNext()) {SelectionKey selectedKey = keysIterator.next();// 检查是否有新的连接请求if (selectedKey.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) selectedKey.channel();SocketChannel client = server.accept();client.configureBlocking(false);// 注册新的SocketChannel到Selector上,监听读取数据事件(OP_READ)client.register(selector, SelectionKey.OP_READ);}// 检查是否有数据可读if (selectedKey.isReadable()) {SocketChannel channel = (SocketChannel) selectedKey.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int numRead = channel.read(buffer);if (numRead == -1) { // 表示客户端关闭了连接selectedKey.cancel();channel.close();} else if (numRead > 0) {// 处理接收到的数据...buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);System.out.println("Received: " + new String(data, StandardCharsets.UTF_8));// 数据读取完成后,可能需要重新注册读取事件// 或者调用clear()/compact()后再次注册buffer.clear();channel.register(selector, SelectionKey.OP_READ);}}// 移除已处理的事件键keysIterator.remove();}}}}
}

在这个例子中:

  • 首先创建了一个Selector实例。
  • 然后打开一个ServerSocketChannel并设置为非阻塞模式,将其绑定到特定端口以监听连接请求。
  • 将ServerSocketChannel注册到Selector上,监听OP_ACCEPT事件,即新的连接请求。
  • 在无限循环中,调用selector.select()阻塞等待事件发生。
  • 当有事件发生时,通过迭代selectedKeys()来处理每个已触发的事件,包括接收新连接和从已有连接读取数据。
  • 对于每一个读取事件,从对应的SocketChannel读取数据,并对数据进行相应处理。
  • 事件处理完毕后,移除已处理的SelectionKey,准备下一轮事件轮询。

注意,实际应用中可能还需要考虑异常处理、数据完整性和线程安全等问题。

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

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

相关文章

Redis安全加固策略:配置文件权限设置 配置本地日志存储目录 连接超时时间限制

Redis安全加固策略&#xff1a;配置文件权限设置 & 配置本地日志存储目录 & 连接超时时间限制 1.1 配置文件权限设置1.2 配置本地日志存储目录1.3 连接超时时间限制 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1.1 配置文件权限…

如何理解template<size_t N>?

template<size_t N> 是C中的模板参数&#xff0c;用于定一个非类型参数的值。它可以在编译时确定&#xff0c;并且可以在编译时进行计算和使用。 例如&#xff0c;我们可以定义一个模板函数&#xff0c;接受一个大小为N的数组作为参数&#xff1a; template<size_t …

Qt/事件分发器/事件过滤器

事件分发器 //事件分发器bool event(QEvent* e); //事件分发器&#xff1a;&#xff1a;用途 分发事件 bool MyLabel::event(QEvent* e) {if(e->type() QEvent::MouseButtonPress){//如果是鼠标摁下 拦截事件 不向下分发QMouseEvent* ev static_cast<QMouseEvent*>…

Qt-Qss 样式表属性大全

目录 前言 源码文件信息 QSS属性大全 1.控件常用的属性 2.控件常用属性值 3.控件常用状态 4.其他 前言 相信很大一部分开发者真的被Qt样式表的属性搞挺头痛的&#xff01; 一方面Qss的示例Demo太过简单&#xff0c; 另一方面&#xff0c;Qss的所有属性在Qt的官方文…

软考高级:逆向工程相关概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Deeplearning4j【基础 01】初识Java深度学习框架DL4J

初识Java深度学习框架DL4J 1.起因2.简介3.组件3.1 Deeplearning4j/ScalNet3.1.1 Deeplearning4jf&#xff08;Java&#xff09;3.1.2 ScalNet&#xff08;Scala&#xff09; 3.2 ND4J/LibND4J3.3 SameDiff3.4 DataVec3.5 Arbiter3.6 RL4J 4.总结 内容来自网络&#xff0c;基于官…

Redis--线程模型详解

Redis线程模型 Redis内部使用的文件事件处理器&#xff08;基于Reactor模式开发的&#xff09;file event handler是单线程的&#xff0c;所以Redis线程模型才叫单线程模型&#xff0c;它采用IO多路复用机制同时监听多个socket&#xff0c;当被监听的socket准备好执行accep、r…

072:vue+cesium 实现下雪效果

第072个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中实现下雪效果,这里使用着色器来实现实例特效。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共120行)着色代码实现心得:专栏目标示例效果

Python世界之附加

一、数据类型转换 1.隐式类型转换 在隐式类型转换中&#xff0c;Python 会自动将一种数据类型转换为另一种数据类型。 对两种不同类型的数据进行运算&#xff0c;较低数据类型就会转换为较高数据类型以避免数据丢失。 2.显式类型转换 在显式类型转换中&#xff0c;用户将对…

Linux设置静态IP地址

在Linux系统中设置静态IP地址的步骤如下&#xff1a; 1.使用管理员权限登录系统。 2.编辑网卡配置文件&#xff1a; 网卡配置文件通常位于 /etc/sysconfig/network-scripts/ 目录下&#xff0c;可以使用命令 cd /etc/sysconfig/network-scripts 切换到该目录。 …

Wifi技术知识

参考文章 https://www.163.com/dy/article/FDFT60T70550I80C.html https://www.zhihu.com/tardis/bd/art/485711752?source_id1001 wifi代数 以前大家看电脑手机路由器参数&#xff0c;WiFi都是802.11a/b/n/g/ac/ax&#xff0c;这学名读起来有些麻烦&#xff0c;现在好了&…

第12届智能计算与无线光通信国际会议(ICWOC 2024)即将召开!

2024年第12届智能计算与无线光通信国际会议&#xff08;ICWOC 2024&#xff09;将于2024年6月21-23日在中国重庆召开。随着深度学习等人工智能技术的不断进步&#xff0c;以自动化、自治为特征的智能应用预计将激增。本届会议主题为“光通信智能链接”&#xff0c;旨在为相关技…

ubuntu环境下docker容器详细安装使用

文章目录 一、简介二、ubuntu安装docker1.删除旧版本2.安装方法一3. 安装方法二&#xff08;推荐使用&#xff09;4.运行Docker容器5. 配置docker加速器 三、Docker镜像操作1. 拉取镜像2. 查看本地镜像3. 删除镜像4. 镜像打标签5. Dockerfile生成镜像 四、Docker容器操作1. 获取…

Qt | TCP服务器端框架搭建

文章目录 server.hserver.cppmain.cpptcpclientsocket.htcpclientsocket.cpptcpserver.htcpserver.cpp提示运行QTcpServer 是 Qt 框架中的一个类,用于实现 TCP 服务器。它提供了一种方便的方式来创建和管理 TCP 服务器,以便与客户端进行通信。QTcpServer 类属于 QtNetwork 模…

Webserver(1): C++实现线程池

在实现线程池之前&#xff0c;首先对线程池中所需要用到的互斥锁、条件变量和信号量进行了简单的封装。 互斥锁、条件变量和信号量封装 locker.h头文件如下&#xff08;已详细注释&#xff09; /* 这里面对互斥锁&#xff0c;条件变量和信号量进行了封装 保证工作队列的线程…

微服务架构的流行框架之:Dubbo Spring Cloud

Dubbo Dubbo是一个高性能、轻量级的开源Java RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;框架&#xff0c;由阿里巴巴开发并贡献给了Apache基金会&#xff0c;成为Apache的顶级项目。Dubbo提供了RPC通信和服务治理的解决方案&#xff0c;使得构…

深入理解C语言中的变量和常量

变量和常量 1. 前言2. 预备知识2.1 printf和%d2.2 \n2.3 scanf2.4 scanf在vs中报错2.5 extern2.6 数组的初始化 3. 变量和常量的区别4. 变量4.1 定义变量的方法4.2 变量的分类4.2.1 局部优先 4.3 变量的使用4.4 变量的作用域4.4.1 局部变量的作用域4.4.2 全局变量的作用域 4.5 …

机器学习|KNN和Kmeans

KNN和Kmeans KNN KNN-K个最近的邻居&#xff0c;而K是可人先预设出来的。 所谓近朱者赤&#xff0c;近墨者黑。 可以选取离当前最近的K个样本来作为辅助判断&#xff0c;因为本样本和最近的K个样本应该是处于一种相似的状态。 以下是一个苹果和梨的识别任务。 图上会出现一个未…

深入Spring Boot核心技术:代码实战解析

第一章&#xff1a;揭开Spring Boot自动配置的面纱 自动配置原理 让我们首先通过一个简化的Spring Boot应用启动类来直观感受自动配置的工作原理&#xff1a; java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.Sprin…

【软件设计师】通俗易懂的去了解算法的时间复杂度

&#x1f413; 时间复杂度 常用排序的时间复杂度 时间频度 算法需要花费的时间&#xff0c;和它语句执行的次数是成正比的&#xff0c;所以会把一个算法种语句执行次数称为语句频度和时间频度、记作T(n)。 定义 时间复杂度就是找到一个无限接近时间频度T(n)同数量级的函数&am…