【Netty】nio阻塞非阻塞Selector

news2024/11/23 5:13:16

阻塞VS非阻塞

阻塞
  • 阻塞模式下,相关方法都会导致线程暂停。

    • ServerSocketChannel.accept() 会在没有建立连接的时候让线程暂停

    • SocketChannel.read()会在没有数据的时候让线程暂停。

    • 阻塞的表现就是线程暂停了,暂停期间不会占用CPU,但线程相当于闲置。

  • 单线程下,阻塞方法之间相互影响,几乎不能正常工作,需要多线程支持。

  • 但多线程下又有新问题。

    • 32 位 jvm 一个线程 320k,64 位 jvm 一个线程 1024k,如果连接数过多,必然导致 OOM,并且线程太多,反而会因为频繁上下文切换导致性能降低

    • 可以采用线程池技术来减少线程数和线程上下文切换,但治标不治本,如果有很多连接建立,但长时间 inactive,会阻塞线程池中所有线程,因此不适合长连接,只适合短连接

服务器端

这个代码只能每次在连接到时候读取一次连接事件,进行遍历,其余事件阻塞,即使有其他的读写事件也没有反回应。

public class TestSocketChannel {
    public static void main(String[] args) throws IOException {
        //开启服务
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //ban
        ssc.bind(new InetSocketAddress(8080));
        List<SocketChannel> channels = new ArrayList<>();
        while (true) {
            //等待建立连接
            SocketChannel sc = ssc.accept();
            channels.add(sc);
            Iterator<SocketChannel> iterator = channels.iterator();
​
            while (iterator.hasNext()) {
​
                SocketChannel channel = iterator.next();
                ByteBuffer buffer = ByteBuffer.allocate(10);
                //读取数据
                int len = channel.read(buffer);
                ByteBufferUtil.debugAll(buffer);
                buffer.clear();
                log.debug("after read...{}", channel);  
            }
​
        }
    }
}

客户端

public class SocketChannelClient {
    public static void main(String[] args) throws IOException {
        SocketChannel sc = SocketChannel.open();
        sc.connect(new InetSocketAddress("localhost", 8080));
        System.out.println("waiting...");
    }
}

非阻塞
  • 非阻塞模式下,相关的方法都不会让线程暂停

    • 在ServerSocketChannel.accept()在没有建立连接时,会返回null.

    • SocketChannel.read在没有数据可读时返回0,但线程不必阻塞,可以执行其他SocketChannel的read或者ServerSocketChannel.accept

    • 写数据的时候,知识等待数据写入channel即可,无需等Channel通过网络把数据发出去。

  • 非阻塞模式下,即使没有连接建立和可读数据,线程任然在不断运行,拜拜浪费CPU

  • 数据复制过程中,线程实际还是阻塞的。(AIO改进的地方)

服务端代码

package com.aqiuo.socketchannel;
​
import com.aqiuo.buffer.ByteBufferUtil;
import lombok.extern.slf4j.Slf4j;
​
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Slf4j
public class TestSocketChannel {
    public static void main(String[] args) throws IOException {
        //开启服务
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //绑定端口
        ssc.bind(new InetSocketAddress(8080));
        ssc.configureBlocking(false); //非阻塞模式
        //连接的集合
        List<SocketChannel> channels = new ArrayList<>();
        while (true) {
            //等待建立连接非阻塞,线程还好继续向下运行,没有连接返回null
            SocketChannel sc = ssc.accept();
            if(sc!=null){
                log.info("connected...{}",sc);
                sc.configureBlocking(false);//非阻塞模式
                channels.add(sc);
            }
            Iterator<SocketChannel> iterator = channels.iterator();
            while (iterator.hasNext()) {
​
                SocketChannel channel = iterator.next();
                ByteBuffer buffer = ByteBuffer.allocate(10);
                //非阻塞读取数据
                //接受客户端发送的数据。没有读到数据返回0
                int len = channel.read(buffer);
                if(len>0){
                    buffer.flip();
                    ByteBufferUtil.debugAll(buffer);
                    buffer.clear();
                    log.info("after read...{}",channel);
                }
​
            }
​
        }
    }
}
 
多路复用

单线程可以搭配Selector完成对多个channel可读可写事件的监控,称之为多路复用

  • 多路复用仅仅针对网络IO,普通文件IO无法利用多路复用。

  • 如果不用Selector的非阻塞模式,线程大部分事件都在做无用功,而Selector能够保证。

    • 有连接事件时采去连接

    • 有可读事件才去读取。

    • 有可写事件才去写入。

      • 限于网络传输能力,Channel 未必时时可写,一旦 Channel 可写,会触发 Selector 的可写事件

Selector

创建
Selector selector = Selector.open();
绑定 Channel 事件

也称之为注册事件,绑定的事件 selector 才会关心

channel.configureBlocking(false);
SelectionKey key = channel.register(selector, 绑定事件);
  • channel 必须工作在非阻塞模式

  • FileChannel 没有非阻塞模式,因此不能配合 selector 一起使用

  • 绑定的事件类型可以有

    • connect - 客户端连接成功时触发

    • accept - 服务器端成功接受连接时触发

    • read - 数据可读入时触发,有因为接收能力弱,数据暂不能读入的情况

    • write - 数据可写出时触发,有因为发送能力弱,数据暂不能写出的情况

监听 Channel 事件

可以通过下面三种方法来监听是否有事件发生,方法的返回值代表有多少 channel 发生了事件

方法1,阻塞直到绑定事件发生

int count = selector.select();

方法2,阻塞直到绑定事件发生,或是超时(时间单位为 ms)

int count = selector.select(long timeout);

方法3,不会阻塞,也就是不管有没有事件,立刻返回,自己根据返回值检查是否有事件

int count = selector.selectNow();

💡 select 何时不阻塞
  • 事件发生时

    • 客户端发起连接请求,会触发 accept 事件

    • 客户端发送数据过来,客户端正常、异常关闭时,都会触发 read 事件,另外如果发送的数据大于 buffer 缓冲区,会触发多次读取事件

    • channel 可写,会触发 write 事件

    • 在 linux 下 nio bug 发生时

  • 调用 selector.wakeup()

  • 调用 selector.close()

  • selector 所在线程 interrupt

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

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

相关文章

DAY03 HTML

文章目录 一 表格1. 表格的语法2. 表格的可选标记3. 不规则的单元格&#xff08;合并单元格&#xff09;4. 表格的属性5. 表格的大小 二 列表1. 有序列表2. 无序列表3. 属性4. 列表的嵌套5. 定义列表【了解】 三 表单(重点)1. 表单的语法2. 表单的控件分类3. input元素4. selec…

jQuery 基本操作

01-简介 jQuery 是一个功能丰富且广泛使用的 JavaScript 库&#xff0c;它简化了 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作。jQuery 通过其易用的 API&#xff0c;使复杂的 JavaScript 编程任务变得更加简单&#xff0c;并且兼容各种浏览器。 1、jQuery特点 简化 DOM …

数据库设计概述-数据库设计内容、数据库设计方法(基于E-R模型的规范设计方法)

一、引言 如何利用关系数据库理论设计一个满足应用系统需求的数据库 二、数据库设计内容 1、数据库设计是基于应用系统需求分析中对数据的需求&#xff0c;解决数据的抽象、数据的表达和数据的存储结构等问题 2、其目标是设计出一个满足应用要求、简洁、高效、规范合理的数…

Python基础教程(三十):math模块

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的巡演(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

Stm32超声波测距实验

一.任务需求 1. 采用stm32F103和HC-SR04超声波模块&#xff0c; 使用标准库或HAL库 定时器中断&#xff0c;完成1或2路的超声波障碍物测距功能。 2. 当前智能汽车上一般配置有12路超声波雷达&#xff0c;这些专用超声波雷达内置了MCU&#xff0c;直接输出数字化的测距结果&am…

分类判决界面---W-H、H-K算法

本篇文章是博主在人工智能等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在AI学习笔记&#…

文件管理—linux(基础IO)

目录 ​编辑 一、C语言文件接口&#xff08;库函数&#xff09; hello.c写文件 hello.c读文件 输出信息到显示器 stdin & stdout & stderr 二、系统文件I/O&#xff08;系统调用&#xff09; hello.c 写文件&#xff1a; hello.c读文件 接口介绍 open open…

基于Java学生选课管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

STM32多种开发环境及生成hex及bin文件介绍

一.STM32开发环境 KEIL系列 &#xff08;1&#xff09;KEIL公司目前有四款独立的嵌入式软件开发工具&#xff0c;即MDK、KEIL C51、KEIL C166、KEIL C251&#xff0c;它们都是KEIL公司品牌下的产品&#xff0c;都基于uVision集成开发环境&#xff0c;其中MDK是RealView系列中…

从零对Transformer的理解(台大李宏毅)

Self-attention layer自注意力 对比与传统cnn和rnn&#xff0c;都是需要t-1时刻的状态然后得到t时刻的状态。我不知道这样理解对不对&#xff0c;反正从代码上看我是这么认为的。而transformer的子注意力机制是在同一时刻产生。意思就是输入一个时间序列&#xff0c;在计算完权…

内存马的错误参数获取,导致原有接口失效解决方案

内存马的错误参数获取&#xff0c;导致接口失效。 前言 java Listener 类型内存马&#xff0c;在使用request.getParameter(String name); 获取请求参数去判断是否是恶意请求的时候&#xff0c;会影响某些框架无法接收到参数。 例子 在Jersey 框架 使用 MultivaluedMap 去接…

MSPM0G3507——创建新的.c.h文件

在项目处点击右键&#xff0c;再点击New File 再命名.c.h即可

mysql中的datetime类型在Java中到底对应哪个时间类型?

因为MySQL中用的是datetime类型&#xff08;年月日 时分秒&#xff09; java.sql.Date 在Java中用 java.sql.Date 接收 但是得到的却只有年月日 前端接收到的是时间戳 java.time.LocalDateTime 在Java中使用 java.time.LocalDateTime 接收 得到的是带时区的时间 前端接收到的…

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇入口差异切换上线IPC管道ATSC任务Impacket套件UI插件

红队内网攻防渗透 1. 内网横向移动1.1 横向移动入口知识点1.1.1、当前被控机处于域内还是域外1.1.1.1 在域内1.1.1.2 不在域内1.1.1.2.1 第一种方法提权到system权限1.1.1.2.2 第二种方法切换用户上线1.1.1.2.3 kerbrute枚举用户1.1.2、当前凭据为明文密码还是HASH1.2 横向移动…

Vue3中使用el-table遇到的问题

我在使用element-plus中el-table组件的时候&#xff0c;对于某一<el-table-column>标签内的内容设置show-overflow-tooltip属性&#xff0c;但这里溢出展示的tooltip的默认样式是无法像el-tooltip标签那样&#xff0c;直接可以修改的。默认的样式是这样&#xff1a; 因此…

江协科技51单片机学习- p11 静态数码管显示

前言&#xff1a; 本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记&#xff0c;在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。 引用&#xff1a; 51单片机入门教程-2…

包含网关的概念及案例演示

包容网关 知识点讲解 包容网关可以看作排他网关和并行网关的结合体。与排他网一样&#xff0c;可以在外出顺序流上定义条件&#xff0c;但与排他网关不同的是&#xff0c; 进行决策判读时&#xff0c;包容网关所有条件为true的后继分支都会被依次执行。如果所有分支条件都为fa…

24年火爆全网的企业信贷产品-民生惠详解

今年&#xff0c;民生惠企业信贷产品非常火爆&#xff01;客户想申请这信用贷款前&#xff0c;先确认下自己是不是在白名单里。有些地区还能加进白名单&#xff0c;不在的话就别申请了&#xff0c;这是专门给受邀的小微企业的。 这款产品的细节是这样的&#xff1a; 额度&am…

实用软件下载:会声会影2023最新安装包及详细安装教程

可以说它不仅符合家庭或个人所需的影片剪辑功能&#xff0c;甚至能够挑战专业级的影片剪辑软件&#xff0c;适合一般大众使用&#xff0c;操作简单易懂&#xff0c;界面简洁明快。从总体上来看影片制作向导模式&#xff0c;只要三个步骤就可快速做出DV影片&#xff0c;入门初学…