BIO和NIO编程(待完善)
目录
IO模型
BIO
NIO
常见问题
IO模型
Java共支持3种网络编程IO模式:BIO,NIO,AIO

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

代码示例:
Server端:
public class BioServer {private static ExecutorService executorService = Executors.newFixedThreadPool(10);public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务器启动成功");while (true) {Socket socket = serverSocket.accept();System.out.println("客户端连接成功");executorService.execute(() -> {try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {String message;while ((message = reader.readLine()) != null) {System.out.println("收到消息: " + message);writer.write("已收到消息: " + message);writer.newLine();writer.flush();}} catch (IOException e) {e.printStackTrace();}});}}
}
Client端:
public class BioClient {public static void main(String[] args) throws IOException {Socket socket = new Socket("localhost", 8888);BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));String message;while ((message = consoleReader.readLine()) != null) {writer.write(message);writer.newLine();writer.flush();System.out.println("发送消息: " + message);System.out.println("收到回复: " + reader.readLine());}socket.close();}
}
执行结果:

存在问题:
- IO操作是阻塞操作, 连接时读写会造成线程阻塞
- 线程太多会造成CPU异常
应用场景:
BIO 方式适用连接数较小且固定的架构, 这种方式对服务器资源要求比较高, 但代码简单易理解。
NIO
同步非阻塞,服务器实现模式为一个线程可以处理多个请求(连接),客户端发送的连接请求都会注册到多路复用器selector上,多路复用器轮询到连接有IO请求就进行处理,JDK1.4开始引入。
应用场景:
NIO方式适用于连接数目多且连接比较短(轻操作) 的架构, 如聊天服务器, 弹幕系统, 服务器间通讯,编程比较复杂。
代码
public class BioSelectorServer {public static void main(String[] args) throws IOException {ServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.socket().bind(new InetSocketAddress(9000));// 设置非阻塞serverSocket.configureBlocking(false);// 创建多路复用器Selector selector = Selector.open();// 注册serversocket到selector, 关注连接事件serverSocket.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务启动成功");while (true) {// 阻塞等待需要处理的事件selector.select();Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();// 如果是连接事件 > 获取连接并且注册读事件if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();SocketChannel socketChannel = server.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接成功");} else if (key.isReadable()) {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(128);int len = socketChannel.read(byteBuffer);if (len > 0) {System.out.println("接收到消息:" + new String(byteBuffer.array()));} else {System.out.println("客户端断开连接");socketChannel.close();}}// 从事件集合里删除本次处理的key,防止下次select重复处理iterator.remove();}}}
}
NIO的三大核心组件:
- channel 类似于流,每个 channel 对应一个 buffer缓冲区,buffer 底层就是个数组
- channel 会注册到 selector 上,由 selector 根据 channel 读写事件的发生将其交由某个空闲的线程处理
- NIO 的 Buffer 和 channel 都是既可以读也可以写

常见问题
为什么Netty使用NIO而不是AIO?
在Linux系统上,AIO的底层实现仍使用Epoll,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层,不容易深度优化,Linux上AIO还不够成熟。Netty是异步非阻塞框架,Netty在NIO上做了很多异步的封装。
相关文章:
BIO和NIO编程(待完善)
目录 IO模型 BIO NIO 常见问题 IO模型 Java共支持3种网络编程IO模式:BIO,NIO,AIO BIO 同步阻塞模型,一个客户端连接对应一个处理线程 代码示例: Server端: public class BioServer {private static …...
基于RocketMQ实现分布式事务
前言 在上一篇文章Spring Boot自动装配原理以及实践我们完成了服务通用日志监控组件的开发,确保每个服务都可以基于一个注解实现业务功能的监控。 而本文我们尝试基于RocketMQ实现下单的分布式的事务。可能会有读者会有疑问,之前我们不是基于Seata完成了…...
TikTok社会学:短视频如何塑造社会认知?
TikTok,作为一款全球性的短视频平台,正在深刻地影响着用户的社会认知。在这个数字时代,短视频不仅仅是娱乐的载体,更是塑造和反映社会认知的一面镜子。本文将深入探讨TikTok是如何通过短视频影响社会认知,以及这种影响…...
小秋SLAM入门实战深度学习所有文章汇总
如何用python代码实现虚拟拖拽 MediaPipe Losses 损失函数 深度学习激活函数Activation Functions 【深度学习Regularization正则化】 深度学习: 数据扩充 (Data Augmentation) 【keras-yolo3】 【YOLO源码解读】 caffe源码解读系列 Python中的异常处理 精确率、精度ÿ…...
linux搭建git仓库
git安装与配置 # git安装 yum install -y git# git配置(以下为root用户下配置) # 添加git组 groupadd git# 添加账号、密码(账号zdtest可根据自己需求修改) useradd zdtest -g git passwd zdtest创建远程仓库(linux端) 创建个人文件夹 mkdir -p /home/data/zdtestcd /home/d…...
19. Mysql 循环语句
文章目录 概念循环语句while 循环语句repeat 循环语句loop 循环语句iterate 和 leave 语句 精选示例总结参考资料 概念 循环结构是编程中常见的控制结构,它允许我们重复执行一段代码,直到满足特定条件为止。 在 Mysql 中,常用来实现各种复杂…...
【qt】解决qt里编辑qss后失效问题(qt编码问题)
1、先创建qss文本stylesheet.qss 以按钮为例 QPushButton {background-color:rgb(240,255,255);color: rgb(0, 0, 2);border-style: outset;border-color: beige;border-radius: 10px; }/* hover按钮悬浮,鼠标悬浮在按钮上的状态,按钮颜色 */QPushButto…...
MySQL数据库高级SQL语句及存储过程
目录 一、高级SQL语句 (一)case语句 1.语法定义 2.示例 (二)空值(NULL) 和 无值( ) 1.区别 2.示例 (1)字符长度 (2)判断方法 ① 空值(NULL) ② 无值( ) (3…...
使用idea构建父子类springboot项目教程
第一步创建一个父类java项目(最外层java项目) 1.点击File 然后点击new 再点击Project 2.点击Maven 配置Java版本 再点击next 3.GroupId:包结构,ArtifactId:项目名称,填写完,点击next 4.点击…...
TCP_可靠数据传输原理
引言 在网络通信中,TCP是确保数据可靠传输的关键协议。但在我们深入研究TCP拥塞控制技术之前,让我们先探索可靠数据传输的原理,特别是TCP头部中一些重要字段的作用。 网络层提供了点对点的通信服务,努力交付数据报,但…...
Python随机点名
python随机点名 # 生成 0 ~ 9 之间的随机数 # 导入 random(随机数) 模块 import random print(random.randint(0,9)) 执行以上代码输出结果为: 4 尝试一下 以上实例我们使用了 random 模块的 randint() 函数来生成随机数,你每次执行后都返回不同的数字&a…...
HarmonyOS4.0系统性深入开发07创建一个ArkTS卡片
创建一个ArkTS卡片 在已有的应用工程中,创建ArkTS卡片,具体操作方式如下。 创建卡片。 根据实际业务场景,选择一个卡片模板。 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单…...
胡润研究院发布《2023胡润中国最具历史文化底蕴品牌榜》
胡润研究院发布《2023胡润中国最具历史文化底蕴品牌榜》,前十名分别是片仔癀、同仁堂、贵州茅台、五粮液、中国银行、中华、黄山、农业银行、建设银行、汾酒。 榜单调研范围涵盖中国内地具有60年以上历史的为消费者提供产品或服务的品牌,综合考察品牌历史…...
MFC编程技巧与范例详解01
目录 1、MFC概述 (1)、MFC为什么不用C语言使用C (2)、MFC的开发模型文档-视图模型 (3)、一个完善的MFC程序应该包括 (4)、MFC常用的类 2、MFC的特性 (1)…...
TPS5430正负电源模块
TPS5430正负电源模块 Chapter1 TPS5430正负电源模块一、芯片重要参数二、tps5430参考电路讲解以及PCB布局1.正压降压(15V转12V)2.正压降负压(15V转-12V) Chapter2 使用tps5430制作正负DC-DC降压电源,tps7a47和tps7a33制…...
【LeetCode 面试经典150题】45. Jump Game II 跳跃游戏II
45. Jump Game II 题目大意 You are given a 0-indexed array of integers nums of length n. You are initially positioned at nums[0]. Each element nums[i] represents the maximum length of a forward jump from index i. In other words, if you are at nums[i], yo…...
RustDesk连接客户端提示key不匹配 Key Mismatch无法连接(已解决)
环境: RustDesk1.1.9 服务端docker部署 问题描述: RustDesk连接客户端提示key不匹配 Key Mismatch无法连接 解决方案: 1.docker部署RustDesk服务检查配置 networks:rustdesk-net:external: falsevolumes:hbbr:hbbs:services:hbbs:container_name: rustdesk-hbbsport…...
puppeteer入门指南
一、简介 Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。 二、使用 1、安装nodejs最新版 2、安装puppeteer-core npm install puppeteer-core 3、编写main.js const puppeteer require(puppeteer-core);(as…...
vue3按钮点击频率控制
现有一个按钮,如下图 点击时 再次点击 刷新窗口再次点击 刷新窗口依然可以实现点击频率控制。 代码实现: <template><!--<el-config-provider :locale"locale"><router-view/></el-config-provider>--><el…...
(一)Matlab数值计算基础
目录 1.2Matlab中的数据类型 1.2Matlab中的数据类型 逻辑型 逻辑型变量值为1或0字符型 MATLAB的字符型输入使用单引号括起来,字符串存储为字符数组,每个元素占一个ASCII字符数值型 数值型分为整型(int)、单精度浮点型࿰…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
