Selector 选择器

简介: Selector 选择器

前言

工欲善其事必先利其器, 讲了好几篇文章的Netty相关, 今天讲一下原始的 Java NIO 的Selector选择器, 本篇将从基本介绍到API相关全部介绍一遍


基本介绍

JavaNIO使用非阻塞的 IO 方式, 可以使用一个线程去处理多个客户端连接, 这个时候就会使用到Selector选择器

Selector可以检测到多个注册的通道上是否有事件发生(多个Channel以事件的方式可以注册到一个Selector上). 如果有事件发生, 就去获取事件然后针对每一个事件进行相应的处理, 这样就实现了只用一个线程去管理多个通道

通过Selector使得只有在连接真正有读写事件发生的时候, 才会进行读写, 大大减少了系统开销

Netty中的 IO线程NioEventLoop聚合了Selector, 可以同时并发的处理成百上千个客户端的连接

API

可以看到Selector是一个抽象类, 如图所示, 是Selector的所有方法, 接下来我们就讲解一下Selector的常用方法

网络异常,图片无法展示
|

  • open(): 得到一个选择器对象
  • select():无超时时间的select过程, 一直等待, 直到发现有CHannel可以进行 IO操作
  • select(long timeout):监控所有注册的Channel, 当其中的CHannel有 IO操作 可以进行时, 将这些Channel对应的SelectionKey找到, 参数用户设置超时时间
  • wakup():唤醒selector
  • selectNow():不阻塞, 立即返回
  • selectKeys():返回所有发生事件的Channel对应的SelectionKey的集合, 通过SelectionKey可以找到对应的Channel
  • keys():返回所有CHannel对应的SelectionKey的集合, 通过SelectionKey能找到对应的CHannel

NIO 中存在ServerSocketChannel功能类似于ServerSocket, SocketCahnnel类似于Select

客户端发起连接时服务端工作流程

示例代码

public static void main(String[] args) throws IOException {
    // 异常向上抛出
    ServerSocketChannel server= ServerSocketChannel.open();
    // 获取一个选择器对象
    Selector selector = Selector.open();
    // 注册 serverSocketChannel 到 selector, 关注 OP_ACCEPT 事件
    server.register(selector, SelectionKey.OP_ACCEPT);
    // 绑定端口
    server.socket().bind(new InetSocketAddress(8888));
    // 设置 serverSocketChannel 为非阻塞模式
    server.configureBlocking(false);
    for (;;){
        // 没有事件发生
        if (selector.select(1000) == 0){
            continue;
        }
        // 有事件发生, 找到发生事件的 Channel 对应的 SelectionKey 的集合
        Set<SelectionKey> selectionKeys = selector.selectedKeys();
        // 遍历
        Iterator<SelectionKey> iterator = selectionKeys.iterator();
        while(iterator.hasNext()){
            final SelectionKey next = iterator.next();
            // 发生 OP_ACCEPT 事件, 处理连接请求
            if (next.isAcceptable()){
                final SocketChannel accept = server.accept();
                // 将 socketChannel 注册到 selector, 关注 OP_READ 事件, 并给 socketChannel 关联 Buffer
                accept.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(2048));
            }
            // 如果是发生读事件, 客户端读取数据
            else if (next.isReadable()){
                final SocketChannel channel = (SocketChannel) next.channel();
                final ByteBuffer buffer =(ByteBuffer) next.attachment();
                channel.read(buffer);
            }
            // 手动从集合中移除当前的 selectionKey, 防止重复处理事件
            iterator.remove();
        }
    }
}
复制代码

在上述服务端示例代码中, 服务端的工作流程为:

  • 当客户端发起连接时, 会通过ServerSocketChannel创建对应的SocketChannel
  • 调用SelectChannel的注册方法将其注册到Selector上, 注册方法会返回一个SelectionKey, 将该SelectionKey放入到SelectionKeys集合中, 此时, SelectKeySelector关联, 也和SocketChannel关联
  • Selector调用select(), select(timeout), selectNow()方法对内部的SelectionKeys中的SelectionKey所对应的SocketChannel进行监听
  • 通过SelectionKey找到有事件发生的SocketChannel, 完成数据处理





目录
相关文章
|
存储 安全 Linux
|
XML Java 测试技术
通义灵码与githubcopilot的对比评测
本文评测了通义灵码,与github copilot在一些代码编写能力上面的能力比较。 虽然github copilot要强很多,但灵码目前的能力也不算很弱,并且在一些小类上会做的更好一些。 值得试试看,也是免费的
59469 10
|
4月前
|
人工智能 边缘计算 安全
AI 技术在少儿英语 APP 中的应用
AI已成少儿英语APP核心驱动力:拟人外教、创意绘图、儿童语音纠错、游戏化关卡与记忆追踪五大场景深度融合,兼顾趣味性、发音耐受度与安全合规(本地处理、防沉迷、COPPA)。2026技术实现&lt;500ms低延时、音素级反馈与个性化学情诊断。(239字)
|
供应链 物联网 区块链
未来科技浪潮之巅:区块链、物联网与虚拟现实的融合趋势
【10月更文挑战第30天】随着科技的不断进步,新兴技术如区块链、物联网和虚拟现实正在逐渐改变我们的生活和工作方式。本文将深入探讨这三种技术的发展趋势和应用场景,以及它们如何相互融合,共同推动未来科技的发展。我们将通过实例分析,展示这些技术在不同领域的实际应用,并探讨它们对未来社会的影响。让我们一起探索这个充满无限可能的未来科技世界!
|
JSON API 数据库
探索FastAPI:不仅仅是一个Python Web框架,更是助力开发者高效构建现代化RESTful API服务的神器——从环境搭建到CRUD应用实战全面解析
【8月更文挑战第31天】FastAPI 是一个基于 Python 3.6+ 类型提示标准的现代 Web 框架,以其高性能、易用性和现代化设计而备受青睐。本文通过示例介绍了 FastAPI 的优势及其在构建高效 Web 应用中的强大功能。首先,通过安装 FastAPI 和 Uvicorn 并创建简单的“Hello, World!”应用入门;接着展示了如何处理路径参数和查询参数,并利用类型提示进行数据验证和转换。
968 0
stm32f407探索者开发板(十五)——NVIC中断优先级管理
stm32f407探索者开发板(十五)——NVIC中断优先级管理
1903 0
|
分布式计算 Hadoop Linux
实验: 熟悉常用的Linux操作和Hadoop操作
实验: 熟悉常用的Linux操作和Hadoop操作
330 2
|
人工智能 达摩院 API
阿里云灵积模型服务Quick Start
DashScope灵积模型服务以模型为中心,致力于面向AI应用开发者提供品类丰富、数量众多的模型选择,并为其提供开箱即用、能力卓越、成本经济的模型服务API。DashScope灵积模型服务依托达摩院等机构的优质模型,在阿里云基础设施之上构建。灵积服务4.11号刚刚开通公测,目前提供Paraformer语音识别API能力,后续通义千问也将通过该服务对外提供API能力。本文演示如何快速通过Python SDK接入服务。
73226 0
阿里云灵积模型服务Quick Start
|
机器学习/深度学习 自然语言处理 算法
每日学术速递3.8
扩散模型(DM)已成为生成模型的新趋势,并展示了强大的条件合成能力。其中,在大规模图像文本对上预训练的文本到图像扩散模型可通过可定制的提示高度控制。与专注于低级属性和细节的无条件生成模型不同,由于视觉语言预训练,文本到图像扩散模型包含更多高级知识。在本文中,我们提出了 VPD(具有预训练扩散模型的视觉感知),这是一种在视觉感知任务中利用预训练文本到图像扩散模型的语义信息的新框架。我们没有在基于扩散的管道中使用预训练的去噪自动编码器,而是简单地将其用作主干,旨在研究如何充分利用所学知识。
261 0
|
小程序 JavaScript
微信小程序添加音乐组件
微信小程序添加音乐组件
微信小程序添加音乐组件

热门文章

最新文章