当前位置: 首页 > news >正文

nio多线程版本

多线程多路复用

多线程NIO,,就是多个线程,每个线程上都有一个Selector,,,比如说一个系统中一个线程用来接收请求,,剩余的线程用来读写数据,,每个线程独立干自己的事,,,
一个线程的多路复用,,虽然不会卡住,,但是执行单个事件的时间过长,也会长时间卡在那里,,,需要开启多个线程,,但是多个线程中执行代码的顺序是不可控的,,一般是在主线程接收到一个新的连接之后,再用子线程中的Selector去关注返回的SocketChannel,
selector.select()是在子线程中执行的,,,关注事件是在主线程执行的,,如果子线程中的selector.select()先阻塞住了,,关注事件的代码就必须等到有新的事件到来,才会往下执行

如果子线程想要监听到这个事件,,注册事件的代码就必须在 selector.select()阻塞的代码的前面,,,但是这个是不可控的,,就需要使用selector.wakeup() 唤醒这个selector.select() 阻塞,,唤醒了之后,后面关注事件的代码就执行了,后面监听到这个关注事件,就会去处理

public class MultiThreadServer {public static void main(String[] args) throws IOException {Thread.currentThread().setName("boss");ServerSocketChannel ssc = ServerSocketChannel.open();ssc.configureBlocking(false);Selector boss = Selector.open();SelectionKey bossKey = ssc.register(boss, 0, null);bossKey.interestOps(SelectionKey.OP_ACCEPT);ssc.bind(new InetSocketAddress(8080));// 可用的核心数   ===》 如果在docker上,,拿到的是物理cpu个数,,而不是容器申请时的个数,,,在jdk10才修复int i1 = Runtime.getRuntime().availableProcessors();Worker[] workers = new Worker[2];for (int i = 0; i < workers.length; i++) {workers[i] = new Worker("worker-"+i);}AtomicInteger index =new AtomicInteger(0);while (true){boss.select();Iterator<SelectionKey> iter = boss.selectedKeys().iterator();while (iter.hasNext()){SelectionKey key = iter.next();iter.remove();if (key.isAcceptable()){SocketChannel sc = ssc.accept();System.out.println("客户端已进入"+sc);sc.configureBlocking(false);System.out.println("before register...");// 轮询选择器,选择一个线程执行workers[index.getAndIncrement() % workers.length].register(sc);//                    worker01.register(sc);// 前面初始化 selector.select()阻塞了
//                    SelectionKey scKey = sc.register(worker01.selector, 0, null);
//                    scKey.interestOps(SelectionKey.OP_READ);System.out.println("after register...");
//                    sc.register()}}}}static class Worker implements Runnable{private Thread thread;private Selector selector;private String name;private ConcurrentLinkedQueue<Runnable> queue = new ConcurrentLinkedQueue<>();private volatile  boolean start = false;// 是否初始化public Worker(String name) {this.name = name;}// 初始化线程和Selectorpublic void register(SocketChannel sc) throws IOException {if (!start){selector = Selector.open();thread = new Thread(this,name);thread.start();start = true;}queue.add(()->{try {sc.register(selector,SelectionKey.OP_READ);} catch (ClosedChannelException e) {throw new RuntimeException(e);}});selector.wakeup();//            sc.register(selector,SelectionKey.OP_READ);
//            // 唤醒阻塞,,, 阻塞住了,,下面的register就无法到达
//            selector.wakeup();}@Overridepublic void run() {while (true){try {selector.select();// 最开始的时候  ,,,run如果先执行,,,queue里面是空的,,注册逻辑放在select()前面也是一样不会将 socketChannel注册进去,, 需要唤醒Runnable task = queue.poll();if (task != null){task.run();}Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()){SelectionKey key = iterator.next();iterator.remove();if (key.isReadable()){ByteBuffer buffer = ByteBuffer.allocate(16);SocketChannel channel = (SocketChannel) key.channel();channel.read(buffer);System.out.println(Thread.currentThread().getName()+"name");debugAll(buffer);}else if(key.isWritable()){}}} catch (IOException e) {throw new RuntimeException(e);}}}}
}
名词
  • 阻塞IO: 用户线程会一直等待,直到数据准备好,才返回,,,就是线程停止,等待数据

  • 非阻塞IO: 用户程序空间操作系统的内核空间 ==》 操作系统会立即返回,,用户线程始终在运行,并没有停下来

  • 多路复用: 通过Selector监测事件,,检测到有事件就会到操作系统内核空间去执行

  • 同步: 线程自己去获取结果

  • 异步: 线程自己不去获取结果,,由另一个线程送结果 (至少有两个线程)

  • 异步IO: 异步都是非阻塞的,,一个线程执行,,通过另一个线程返回结果,,,

阻塞IO是同步的,,也叫同步阻塞,,,
非阻塞IO也是同步的,也叫同步非阻塞
多路复用也是同步的,,只是将所有的事件都集中到一起处理

零拷贝

在这里插入图片描述

一般的文件读取,都是要经过内核空间用户空间 ,再从用户空间 拷贝到 缓冲区, 一个文件要拷贝很多次,,才能发送出去,,
零拷贝: 就是让文件拷贝,不再经过用户空间,,直接就用操作系统内核空间里面的数据。。
零拷贝适合那种小文件拷贝,,因为大文件会占用很多内核缓冲区,,可能会影响别的IO操作

// 堆外内存(direct buffer) : 直接分配在堆外的内存,减少从堆内存到直接内存的拷贝
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
AIO(Asynchronous IO) 异步输入输出

非阻塞IO,,需要一个回调函数,去传递 执行完成之后返回的结果

public class Demo01 {/*** linux 对异步IO不友好,,, 底层只是用多路复用模拟了一个异步IO,,,性能上没有优势* window系统通过IOCP实现了真正的异步IO***/public static void main(String[] args) throws IOException, InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(1);// 异步IO必须是多个线程,,,一个线程发起,一个线程送结果Path path = Paths.get("/Users/chenjie/code/learn/learn-netty/learn-netty/netty01/src/main/resources/word.txt");System.out.println(Files.exists(path));try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)) {ByteBuffer buffer = ByteBuffer.allocate(8);ByteBuffer attachBuffer = ByteBuffer.allocate(8);System.out.println("read begin:"+Thread.currentThread().getName());/*** params: ByteBuffer* params2: 读取的起始位置* params3: 附件 : 万一一次读不完,,需要一个bytebuffer接着读* params4: 真正结果出来了,调用这个回调方法*/channel.read(buffer,0,attachBuffer,new CompletionHandler<Integer, ByteBuffer>(){@Overridepublic void completed(Integer result, ByteBuffer attachment) {// 当你的文件正确读取完毕后attachment.flip();debugAll(attachment);System.out.println(Thread.currentThread().getName()+"hehe");countDownLatch.countDown();}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.out.println("exc = " + exc);System.out.println(exc.getMessage()+"e");}});System.out.println("read finished");countDownLatch.await();} catch (IOException e) {throw new RuntimeException(e);}}}

相关文章:

nio多线程版本

多线程多路复用 多线程NIO&#xff0c;&#xff0c;就是多个线程&#xff0c;每个线程上都有一个Selector&#xff0c;&#xff0c;&#xff0c;比如说一个系统中一个线程用来接收请求&#xff0c;&#xff0c;剩余的线程用来读写数据&#xff0c;&#xff0c;每个线程独立干自…...

Electron、Tauri及其它跨平台方案终极对比

Electron、Tauri及跨平台方案终极对比&#xff08;2025版&#xff09; 一、核心框架深度解析 1.1 Electron&#xff1a;Web技术的桌面霸主 技术架构 基于Chromium&#xff08;浏览器内核&#xff09; Node.js&#xff08;后端运行时&#xff09;的双进程架构&#xff0c;支持…...

蓝桥杯试题:二分查找

一、问题描述 给定 n 个数形成的一个序列 a&#xff0c;现定义如果一个连续子序列包含序列 a 中所有不同元素&#xff0c;则该连续子序列便为蓝桥序列&#xff0c;现在问你&#xff0c;该蓝桥序列长度最短为多少&#xff1f; 例如 1 2 2 2 3 2 2 1&#xff0c;包含 3 个不同的…...

MongoDB Chunks核心概念与机制

1. 基础定义‌ ‌Chunk&#xff08;块&#xff09;‌&#xff1a;MongoDB分片集群中数据的逻辑存储单元&#xff0c;由一组连续的片键&#xff08;Shard Key&#xff09;范围数据组成&#xff0c;默认大小为‌64MB‌&#xff08;可调整范围为1-1024MB&#xff09;‌。‌数据分…...

决策树(Decision Tree):机器学习中的经典算法

1. 什么是决策树&#xff1f; 决策树&#xff08;Decision Tree&#xff09;是一种基于树形结构的机器学习算法&#xff0c;适用于分类和回归任务。其核心思想是通过一系列的规则判断&#xff0c;将数据集不断划分&#xff0c;最终形成一棵树状结构&#xff0c;从而实现预测目…...

高频 SQL 50 题(基础版)_1084. 销售分析 III

高频 SQL 50 题&#xff08;基础版&#xff09;_1084. 销售分析 III 思路 思路 select t1.product_id,product_name from Product as t1 join(select product_id,min(sale_date) as min_date,max(sale_date) as max_datefrom Salesgroup by (product_id)having 2019-01-01<…...

Python-selenium启动edge打开百度

文章目录 专栏导读1、背景2、代码总结 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门针对于有爬虫基础准备的一套基础教学&#xff0c;轻松掌握Python爬虫&#xff0c;欢迎各位同学订阅&#xff0c;专栏订阅地址…...

网络安全需要掌握哪些技能?

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在这个高度依赖于网络的时代&#xff0c;网络安全已经成为我们工作和生活中不可或缺的一部分&#xff0c;更是0基础转行IT的首选&#xff0c;可谓是前景好、需求大…...

自动扶梯人员摔倒掉落识别检测数据集VOC+YOLO格式5375张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;5375 标注数量(xml文件个数)&#xff1a;5375 标注数量(txt文件个数)&#xff1a;5375 …...

中国棒球国家队征战世界棒球经典赛·棒球1号位

中国棒球国家队在世界棒球经典赛预选赛中的表现备受瞩目。以下是对中国棒球国家队参与此次预选赛的详细介绍&#xff1a; 一、预选赛背景与分组 • 赛事背景&#xff1a;世界棒球经典赛&#xff08;World Baseball Classic&#xff0c;简称WBC&#xff09;是由世界棒垒联授权&…...

重生之数据结构与算法----数组链表

简介 数据结构的本质&#xff0c;只有两种结构&#xff0c;数组与链表。其它的都是它的衍生与组合算法的本质就是穷举。 数组 数组可以分为两大类&#xff0c;静态数组与动态数组。静态数组的本质是一段连续的内存&#xff0c;因为是连续的&#xff0c;所以我们可以采用偏移量的…...

计算机网络常见疑问

tcpip模型没有数据链路层&#xff0c;那课本学的五层模型数据链路层的流量控制可靠传输是事实还是理论&#xff1f; 在计算机网络中&#xff0c;TCP/IP模型与OSI五层模型的分层差异确实容易引发疑问&#xff0c;尤其是关于数据链路层&#xff08;五层模型&#xff09;的功能是…...

C++07(继承)

文章目录 面向对象之继承继承相关概念派⽣类声明派⽣类的成员访问属性派⽣类的构造函数与析构函数 面向对象编程编程思想面向对象编程涉及到两个重要的概念类类型的定义**类中数据成员的定义**构建对象成员访问成员访问修饰符——限制成员的可见性构造函数析构函数静态成员共用…...

文件上传漏洞:upload-labs靶场1-10

目录 文件上传漏洞介绍 定义 产生原因 常见危害 漏洞利用方式 upload-labs详解 pass-01 pass-02 pass-03 pass-04 pass-05 pass-06 pass-07 pass-08 pass-09 pass-10 文件上传漏洞介绍 定义 文件上传漏洞是指网络应用程序在处理用户上传文件时&#xff0c;没有…...

【Python/Pytorch】-- 创建3090Ti显卡所需环境

文章目录 文章目录 01 服务器上&#xff0c;存在三个anaconda&#xff0c;如何选择合适的&#xff0c;创建python环境&#xff1f;02 conda、anaconda、cuda、cudnn区别03 用到一些指令04 如何指定cuda的版本&#xff1f;05 conda跟pip的区别&#xff1f;06 pycharm控制台07 服…...

自然语言转SQL之Vanna.ai:AI集成数据库

自然语言转SQL之Vanna.ai&#xff1a;AI集成数据库 一、Vanna.ai是什么二、落地步骤&#xff1a;实现三层需求2.1 官方示例看效果2.2 对接自己的数据库2.3 完全本地化之路 三、构建自己的产品3.1 提问转SQL3.2 执行SQL查询实例2 要实现的功能就是&#xff1a;用中文语言同数据库…...

【零基础到精通Java合集】第二十二集:CMS收集器详解(低延迟的里程碑)

课程标题:CMS收集器详解——低延迟垃圾回收的经典实现(15分钟) 目标:掌握CMS核心工作原理、适用场景与调优策略,理解其在高并发场景下的价值与局限性 0-1分钟:课程引入与CMS设计目标 以“高速公路不停车收费”类比CMS核心思想:在用户线程运行的同时并发回收垃圾,最大…...

2025-03-04 学习记录--C/C++-PTA 习题5-5 使用函数统计指定数字的个数

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 二、代码&#xff08;C语言&#xff09;⭐️ #include <stdio.h>int CountDigit( int number, int di…...

SP导入模型设置

法线贴图格式 Blender,Unity选择OpenGL UE,3DMax选择DirectX...

计算机网络——IP地址

一、IP地址是什么&#xff1f; 定义 IP地址是互联网协议&#xff08;Internet Protocol&#xff09;为每台联网设备分配的唯一标识符&#xff0c;由一串数字&#xff08;IPv4&#xff09;或字母与数字组合&#xff08;IPv6&#xff09;构成。 核心作用&#xff1a;定位设备位置…...

学习刷题公众号管理系统

功能特点支持视频、音频、图文三种课程形式&#xff0c;按知识点分类管理&#xff0c;支持自由添加和编辑课程章节。课程可设置为免费或付费模式&#xff0c;支持VIP会员免费学习权限设置。提供智能组卷功能&#xff0c;学员可按知识点自主组卷&#xff0c;系统从题库中随机抽题…...

人工智能导论:模型与算法(未来发展与趋势)

9 人工智能未来发展和趋势 人工智能作为引领新一轮科技革命和产业变革的战略性技术&#xff0c;正在深刻改变人类社会。本章从类脑计算、自动化机器学习、神经网络压缩、人工智能芯片、量子机器学习、人工智能伦理与治理、人工智能算法开发框架等方面&#xff0c;简要总结人工智…...

避坑指南:STM32 HAL库SPI读写W25Q64时,你可能遇到的时序问题和调试技巧

STM32 HAL库SPI驱动W25Q64实战&#xff1a;时序陷阱与波形诊断全解析 当你的SPI Flash突然开始"装聋作哑"&#xff0c;返回的不是预期数据而是清一色的0xFF或0x00时&#xff0c;这往往不是芯片的罢工抗议&#xff0c;而是时序对话中的"鸡同鸭讲"。本文将带…...

2025届学术党必备的AI辅助写作方案实测分析

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 跟着学术钻研持续深入&#xff0c;开题报告身为钻研项目要紧起点&#xff0c;它的质量径直作…...

RISC-V双芯架构在智慧燃气报警器中的系统级设计与工程实践

1. 项目概述&#xff1a;当RISC-V芯遇上智慧燃气最近在深圳的智慧燃气发展论坛上&#xff0c;我注意到一家叫微五科技的芯片设计公司&#xff0c;他们带来了一套挺有意思的解决方案。核心不是别的&#xff0c;正是当下在嵌入式领域越来越火的RISC-V架构。他们这次重点展示的&am…...

Linux ISP驱动全流程解析:从V4L2框架到图像处理管线

1. 项目概述&#xff1a;从用户按下快门到ISP驱动当我们用手机或相机拍照时&#xff0c;屏幕上那个“咔嚓”的动画和瞬间生成的图片&#xff0c;背后是一场从物理世界到数字世界的精密“接力赛”。这场接力赛的第一棒是镜头和传感器&#xff0c;它们负责捕捉光线。但传感器输出…...

别只会用!cat了:在Kaggle Notebook里动态编辑YOLOv5配置文件的完整攻略

突破Kaggle只读限制&#xff1a;YOLOv5配置文件动态编辑全指南 在Kaggle Notebook中进行计算机视觉项目开发时&#xff0c;许多开发者都遇到过这样的困境&#xff1a;当需要修改YOLOv5模型配置文件时&#xff0c;发现Kaggle的/kaggle/input目录是只读的。本文将介绍三种专业级解…...

告别刷机兼容性噩梦:AnyKernel3如何让Android内核适配变得轻松

告别刷机兼容性噩梦&#xff1a;AnyKernel3如何让Android内核适配变得轻松 【免费下载链接】AnyKernel3 AnyKernel, Evolved 项目地址: https://gitcode.com/gh_mirrors/an/AnyKernel3 还在为不同Android设备的内核适配而烦恼吗&#xff1f;每次发布新内核都要为不同ROM…...

全域矩阵系统的底层逻辑:从流量分散到流量聚合的技术解法

矩阵运营最大的坑&#xff0c;不是做不起来&#xff0c;是做着做着就散了。账号在A平台火了&#xff0c;B平台没动静&#xff1b;今天发了20条&#xff0c;明天只剩3条能坚持——问题的本质不是能力不够&#xff0c;是缺乏一套把分散流量聚合起来的全域矩阵系统架构。一、全域流…...

使用curl命令直接测试taotoken api的连通性与基础功能

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用curl命令直接测试taotoken api的连通性与基础功能 基础教程类&#xff0c;面向需要快速验证或在不便安装SDK的环境中进行操作的…...