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

BIO,NIO,AIO

IO模型

用什么样的通道进行数据传输和接收,java支持3种io网络编程模式 BIO NIO AIO

BIO

同步阻塞 一个客户端连接对应一个处理线程

在这里插入图片描述
BIO示例代码(客户端和服务端)

package com.tuling.bio;import java.io.IOException;
import java.net.Socket;public class SocketClient {public static void main(String[] args) throws IOException, InterruptedException {Socket socket = new Socket("127.0.0.1", 9000);//向服务端发送数据socket.getOutputStream().write("HelloServer".getBytes());socket.getOutputStream().flush();System.out.println("向服务端发送数据结束");byte[] bytes = new byte[1024];//接收服务端回传的数据socket.getInputStream().read(bytes);System.out.println("接收到服务端的数据:" + new String(bytes));socket.close();}
}
package com.tuling.bio;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class SocketServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(9000);while (true) {System.out.println("等待连接。。");//阻塞方法Socket clientSocket = serverSocket.accept();System.out.println("有客户端连接了。。");new Thread(new Runnable() {@Overridepublic void run() {try {handler(clientSocket);} catch (IOException e) {e.printStackTrace();}}}).start();}}private static void handler(Socket clientSocket) throws IOException {byte[] bytes = new byte[1024];System.out.println("准备read。。");//接收客户端的数据,阻塞方法,没有数据可读时就阻塞int read = clientSocket.getInputStream().read(bytes);System.out.println("read完毕。。");if (read != -1) {System.out.println("接收到客户端的数据:" + new String(bytes, 0, read));}clientSocket.getOutputStream().write("HelloClient".getBytes());clientSocket.getOutputStream().flush();}
}

先启动服务端,再启动客户端,客户端和服务端直接可以互发消息
缺点:io代码里read操作是阻塞操作,如果连接不做数据读写操作会导致线程阻塞,浪费资源
如果线程很多,会导致服务器线程太多,压力太大
应用场景:连接数目小且固定的架构,对服务器资源要求比较高

NIO

同步非阻塞 一个线程可以处理多个请求。 客户端发送的请求可以注册到多路复用selector上,多路复用查询到IO请求就进行处理

应用场景 连接多且连接比较短的架构,如聊天服务器,编程比较复杂

nio示例代码

package com.tuling.nio;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;public class NioServer {// 保存客户端连接static List<SocketChannel> channelList = new ArrayList<>();public static void main(String[] args) throws IOException {// 创建NIO ServerSocketChannel,与BIO的serverSocket类似ServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.socket().bind(new InetSocketAddress(9000));// 设置ServerSocketChannel为非阻塞serverSocket.configureBlocking(false);System.out.println("服务启动成功");while (true) {// 非阻塞模式accept方法不会阻塞,否则会阻塞// NIO的非阻塞是由操作系统内部实现的,底层调用了linux内核的accept函数SocketChannel socketChannel = serverSocket.accept();if (socketChannel != null) { // 如果有客户端进行连接System.out.println("连接成功");// 设置SocketChannel为非阻塞socketChannel.configureBlocking(false);// 保存客户端连接在List中channelList.add(socketChannel);}// 遍历连接进行数据读取Iterator<SocketChannel> iterator = channelList.iterator();while (iterator.hasNext()) {SocketChannel sc = iterator.next();ByteBuffer byteBuffer = ByteBuffer.allocate(128);// 非阻塞模式read方法不会阻塞,否则会阻塞int len = sc.read(byteBuffer);// 如果有数据,把数据打印出来if (len > 0) {System.out.println("接收到消息:" + new String(byteBuffer.array()));} else if (len == -1) { // 如果客户端断开,把socket从集合中去掉iterator.remove();System.out.println("客户端断开连接");}}}}
}

nio引入多路复用器示例代码

package com.tuling.nio;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;
import java.util.Set;public class NioSelectorServer {public static void main(String[] args) throws IOException {// 创建NIO ServerSocketChannelServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.socket().bind(new InetSocketAddress(9000));// 设置ServerSocketChannel为非阻塞serverSocket.configureBlocking(false);// 打开Selector处理Channel,即创建epollSelector selector = Selector.open();// 把ServerSocketChannel注册到selector上,并且selector对客户端accept连接操作感兴趣SelectionKey selectionKey = serverSocket.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务启动成功");while (true) {// 阻塞等待需要处理的事件发生selector.select();// 获取selector中注册的全部事件的 SelectionKey 实例Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();// 遍历SelectionKey对事件进行处理while (iterator.hasNext()) {SelectionKey key = iterator.next();// 如果是OP_ACCEPT事件,则进行连接获取和事件注册if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();SocketChannel socketChannel = server.accept();socketChannel.configureBlocking(false);// 这里只注册了读事件,如果需要给客户端发送数据可以注册写事件SelectionKey selKey = socketChannel.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接成功");} else if (key.isReadable()) {  // 如果是OP_READ事件,则进行读取和打印SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocateDirect(128);int len = socketChannel.read(byteBuffer);// 如果有数据,把数据打印出来if (len > 0) {System.out.println("接收到消息:" + new String(byteBuffer.array()));} else if (len == -1) { // 如果客户端断开连接,关闭SocketSystem.out.println("客户端断开连接");socketChannel.close();}}//从事件集合里删除本次处理的key,防止下次select重复处理iterator.remove();}}}
}

NIO三大核心组件: channel buffer selector
channel 通道 ,底层数组
buffer 缓冲
在这里插入图片描述
nio底层在jdk1.4版本基于linux内核函数select()或poll()来实现,类似于nioserver代码,每次都会轮询所有的channel。看哪个有读取事件即进行处理,没有继续遍历。 jdk1.5后引入epoll基于事件相应来优化nio

在这里插入图片描述
AIO 异步非阻塞 一般用于连接数多且连接时间较长的应用 jdk7支持

为什么netty 使用NIO而不是AIO
在linux系统,aio底层仍然使用epoll,没有很好实现AIO,性能没有明显优势,而且被jdk封装不易优化。
netty是异步非阻塞框架,对于aio做了很多异步封装

相关文章:

BIO,NIO,AIO

IO模型 用什么样的通道进行数据传输和接收&#xff0c;java支持3种io网络编程模式 BIO NIO AIO BIO 同步阻塞 一个客户端连接对应一个处理线程 BIO示例代码&#xff08;客户端和服务端&#xff09; package com.tuling.bio;import java.io.IOException; import java.net.So…...

代码随想录刷题-数组-有序数组的平方

文章目录有序数组的平方习题暴力排序双指针有序数组的平方 本节对应代码随想录中&#xff1a;代码随想录&#xff0c;讲解视频&#xff1a;有序数组的平方_哔哩哔哩_bilibili 习题 题目链接&#xff1a;977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 给你一…...

【玩转c++】stack和queue的介绍和模拟实现

本期主题&#xff1a;list的讲解和模拟实现博客主页&#xff1a; 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐stack的介绍和使用1.1.stack的介绍1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上…...

Linux order(文件、磁盘、网络、系统管理、备份压缩)

1. Linux 文件命令 -rwxrwxrwx chmod&#xff1a;change mode&#xff0c;用于&#xff08;文件所有者或 root &#xff09;变更用户(u:owner g:group o:other a:all)的权限 chmod [OPTION]… MODE[,MODE]… FILE… OPTION -R&#xff1a;递归修改more option&#xff1a;chmod…...

最详细的CentOS7安装Mysql数据库服务

1.查看是否安装mysql: rpm -qa | grep mysql如果有查出来东西&#xff0c;使用命令删除&#xff1a; rpm -e xxx2.检查是否有mysql用户组和mysql用户,没有就添加有就忽略&#xff1a; groups mysql 添加用户组和用户 groupadd mysql && useradd -r -g mysql mysql&a…...

【IoT】项目管理:如何做好端到端的项目管理?

今天主要来谈谈项目管理这个话题。 首先来看一个我在网络上看到的一个关于项目管理的案例或者是段子。 将项目管理的作用及意义非常直观地展示了出来。 有一个植树搞绿化的企业&#xff0c;在公司内部设置有五个部门&#xff0c;分别是&#xff1a; 运输部门&#xff1b;挖坑部…...

渲染十万条数据就把你难住了?不存在的!

虚拟列表的使用场景如果我想要在网页中放大量的列表项&#xff0c;纯渲染的话&#xff0c;对于浏览器性能将会是个极大的挑战&#xff0c;会造成滚动卡顿&#xff0c;整体体验非常不好&#xff0c;主要有以下问题&#xff1a;页面等待时间极长&#xff0c;用户体验差CPU计算能力…...

编程学习的心路历程和困惑回顾

回首入行9年的经历&#xff0c;从大一开始学习C语言和数据结构&#xff0c;老师一直是在用IDE演示程序的编写和运行&#xff0c;我们也就一直在跟黑乎乎的命令行窗口打交道。 后来在一些课程的实验环节&#xff0c;接触到了一些别人编写好的工程代码&#xff0c;知道了Makefile…...

请介绍类加载过程,什么是双亲委派模型?

第23讲 | 请介绍类加载过程&#xff0c;什么是双亲委派模型&#xff1f; Java 通过引入字节码和 JVM 机制&#xff0c;提供了强大的跨平台能力&#xff0c;理解 Java 的类加载机制是深入 Java 开发的必要条件&#xff0c;也是个面试考察热点。 今天我要问你的问题是&#xff0…...

Navisworks编辑材质和Revit快速切换材质问题

一、如何在Navisworks2016中编辑材质 初次使用NW2016-2017时发现&#xff0c;原来用于创建编辑材质的小地球不见了&#xff0c;如图1所示&#xff0c;在各大技术群里求助没有回应&#xff0c;度娘搜索也总是摇头。 经过仔细排查可能出现的地方&#xff0c;终于找到了可以编辑材…...

Object对象键值的输出循序到底如何排列的?

1.日常摸鱼看八股 今天又是复习八股文的一天&#xff0c;发现还是彻底懂得原理才好和面试官吹牛批呀。 接着来看看我chat大宝贝的回答&#xff1a; 在现代浏览器中&#xff0c;Object 对象的键值输出循序是比较稳定的&#xff0c;通常是按照如下顺序输出&#xff1a; 所有的数…...

气泡式水位计的安装方法详解

气泡水位计的安装实际上就是气管的安装&#xff0c;气管的安装是否正确将直接影响到仪器测量数据的结果&#xff0c;气泡水位计它由活塞泵产生的压缩空气流经测量管和气泡室&#xff0c;进入被测的水体中&#xff0c;测量管中的静压力与气泡室上的水位高度成正比。那么接下来就…...

求“二维随机变量的期望E(X)与方差D(X)”例题(一)

离散型 设随机变量(X,Y)的联合分布律为 X\Y0100.10.210.30.4 (1)求E(X) 先求x的边缘分布律&#xff0c;表格里x0的概率为0.10.2&#xff0c;于是我们可得 X01P0.30.7直接求E(X)即可&#xff0c;得到结果 (2)求E(XY) 直接x与y相乘就行。 记得别乘多了&#xff0c;别的算了又…...

MySQL 搞定行转列,列转行

行转列方法总结1、使用case…when…then2、使用SUM(IF()) 生成列3、使用SUM(IF()) 生成列 WITH ROLLUP 生成汇总行4、使用SUM(IF()) 生成列 UNION 生成汇总行,并利用 IFNULL将汇总行标题显示为 Total5、使用SUM(IF()) 生成列&#xff0c;直接生成汇总结果&#xff0c;不再利用…...

正点原子裸机开发之C语言点灯程序

一. 简介 本文针对 IMX6ULL 的裸机开发的&#xff08;即不带Linux操作系统的开发&#xff09;。 主要分两部分的工作&#xff1a; 1. 配置 C语言运行环境 2. C 语言编写及运行 二. 配置C语言运行环境 配置 C 语言运行环境的工作分 三部分。如下&#xff1a; 1. 设置…...

cv::阈值分割OTUS原理+代码

opencv库的阈值分割分为全局分割和局部分割全局分割&#xff1a;普通分割ret1,th1 cv2.threshold(img,127, 255, cv2.THRESH_BINARY) #127为阈值 #cv2.THRESH_BINARY |cv2.THRESH_BINARY_INV | cv2.THRESH_TRUNC|cv2.THRESH_TOZERO|cv2.THRESH_TOZERO_INV局部分割&#xff1a;…...

Postgresql-12.5 visual studio-2022 windows 添加pg工程并调试

pg内核学习&#xff0c;记录一下 文章目录安装包编译安装VS添加Postgresql工程调试源码安装包 &#xff08;1&#xff09;perl下载 https://www.perl.org/get.html &#xff08;2&#xff09;diff下载 http://gnuwin32.sourceforge.net/packages/diffutils.htm &#xff08;…...

长沙学院2023 第一次蓝桥训练题解

每道题都在洛谷上&#xff0c;每个题都有很详细的题解&#xff0c;可以先自行做&#xff0c;不会再看题解。 题目解析思路都写在代码中&#xff0c;中文题面就不单独解释题意了。 P2440 木材加工&#xff08;二分答案&#xff09; 链接&#xff1a;P2440 木材加工 解析 代码…...

云端Docker搭建ABY库以及本地CLion使用

文章目录ABY的搭建以及使用前言ABY库的下载、安装及测试CLion配置后续杂项项目改名使用其他的库最后ABY的搭建以及使用 前言 仅做记录&#xff0c;仅供参考&#xff0c;不同人有不同的使用方式命令手敲&#xff0c;可能有错&#xff0c;自己辨识勿问&#xff0c;我懂的也不多…...

ES6-箭头函数、解构赋值、对象简写

箭头函数特点 1、 (只有1个形参) 可以省略() 2、 {} 可以省略 只有一句代码 或 只有返回值的时候,省略return 3、arguments 不可用&#xff0c;arguments在没有形参的时候可以拿到调用函数拿在的实参 获取伪数组通过Array.from转为真数组。 4、 箭头函数没有this&#xff0c; …...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...