NIO的实战教程(简单且高效)

1. 参考

建议按顺序阅读以下三篇文章
为什么NIO被称为同步非阻塞?
Java IO 与 NIO:高效的输入输出操作探究
【Java.NIO】Selector,及SelectionKey

2. 实战

我们将模拟一个简单的HTTP服务器,它将响应客户端请求并返回一个固定的响应(”Hello, World!”)。我们将使用IO和NIO两种不同的方式实现此服务器。
2.1 传统阻塞IO

import java.io.*;
public class TraditionalIOExample {public static void main(String[] args) {try {// 打开文件InputStream input = new FileInputStream("example.txt");OutputStream output = new FileOutputStream("output.txt");// 读取和写入数据int data;while ((data = input.read()) != -1) {output.write(data);}// 关闭文件input.close();output.close();} catch (IOException e) {e.printStackTrace();}}
}

2.2 非阻塞NIO

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;public class NioHttpServer {public static void main(String[] args) {try {// 创建服务端通道ServerSocketChannel serverChannel = ServerSocketChannel.open();// 绑定访问端口serverChannel.socket().bind(new InetSocketAddress(8080));// 通道设置为非阻塞serverChannel.configureBlocking(false);// 通过open方法创建一个SelectorSelector selector = Selector.open();/** 必须将channel注册到selector上,并订阅OP_ACCEPT事件SelectionKey.OP_CONNECT  channel成功连接到另一个服务器称为”连接就绪“SelectionKey.OP_ACCEPT	 server socket channel准备好接收新进入的连接称为”接收就绪“SelectionKey.OP_READ	 有数据可读的通道可以说是”读就绪“SelectionKey.OP_WRITE	 有数据可写的通道可以说是”读就绪“*/serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 返回你所感兴趣的事件(连接,接受,读或写)已经准备就绪的那些通道int readyChannels = selector.select();if (readyChannels == 0){continue;}// 访问”已选择键集“中的就绪通道Set<SelectionKey> selectedKeys = selector.selectedKeys();// 可以遍历这个已选择的集合来访问就绪的通道Iterator<SelectionKey> keyIterator = selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();// 注意每次迭代末尾的remove()调用,Selector不会自己从已选择集中移除SelectioKey实例,必须在处理完通道时自己移除。keyIterator.remove();// 一个server socket channel准备号接收新进入的连接称为”接收就绪“if (key.isAcceptable()) {ServerSocketChannel server = (ServerSocketChannel) key.channel();// 客户端socker注册进来SocketChannel clientChannel = server.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);// 客户端通道是否有数据流进来} else if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);clientChannel.read(buffer);buffer.flip();byte[] bytes = new byte[buffer.remaining()];buffer.get(bytes);String request = new String(bytes);String response = "HTTP/1.1 200 OK\r\n\r\nHello, World!\r\n";ByteBuffer responseBuffer = ByteBuffer.wrap(response.getBytes());clientChannel.write(responseBuffer);clientChannel.close();}}}} catch (IOException e) {e.printStackTrace();}}
}

3. 模型

上述代码结合该模型,第二次阅读代码,会有更深的理解
在这里插入图片描述

4. 原理

多路复用才是NIO不阻塞的原因

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS(五) -- 动效实现(立体盒子旋转-四方体+正六边)

一. 四面立体旋转 正方形旋转 小程序中 wxss中 <!-- 背景 --><view class"dragon"><!--旋转物体位置--><view class"dragon-position"><!--旋转 加透视 有立体的感觉--><view class"d-parent"><view …

计算机操作系统学习笔记

一、什么是操作系统 1、概念 操作系统&#xff08;operating system&#xff0c;简称OS&#xff09;是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入设备与输出设备、操作网络与管理文件系统等基本事务。 …

什么是MVC?MVC框架的优势和特点

目录 一、什么是MVC 二、MVC模式的组成部分和工作原理 1、模型&#xff08;Model&#xff09; 2、视图&#xff08;View&#xff09; 3、控制器&#xff08;Controller&#xff09; 三、MVC模式的工作过程如下&#xff1a; 用户发送请求&#xff0c;请求由控制器处理。 …

C练习题13答案

单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 1.结构化程序由三种基本结构组成、三种基本结构组成的算法是(A) A.可以完成任何复杂的任务 B. 只能完成部分复杂的任务 C. 只能完…

wordpress主题modown v8.81+erphpdown v16.0无限制无授权开心版

修复bug&#xff08;v8.81 2023.03.07&#xff09; 新增文章页正文下面常见问题手风琴模块&#xff0c;可设置显示文章的更新日期而不是发布日期&#xff0c;首页幻灯片支持指定文章、支持一个大图4个小图显示&#xff0c;grid网格列表支持显示简介&#xff0c;前台个人中心里显…

Vue简介

聚沙成塔每天进步一点点 ⭐ 专栏简介 Vue学习之旅的奇妙世界 欢迎大家来到 Vue 技能树参考资料专栏!创建这个专栏的初衷是为了帮助大家更好地应对 Vue.js 技能树的学习。每篇文章都致力于提供清晰、深入的参考资料,让你能够更轻松、更自信地理解和掌握 Vue.js 的核心概念和技…

15-Echarts简化系列之:geo 地理坐标系,地图资源基本绘制和配置项使用

Echarts版本&#xff1a;5.4.3 geo&#xff1a;地理坐标系组件用于地图的绘制&#xff0c;支持在地理坐标系上绘制散点图&#xff0c;线集。绘制地图的数据源可支持 geojson和 svg 格式。 本文章中提供 实例代码 和地图 静态资源 &#xff0c;项目以 react ts 为主&#xff0…

uniapp中使用封装步骤条组件

针对步骤条封装完终于清清楚楚啦 先看效果&#xff1a; 附上代码&#xff1a;使用可直接复用&#xff1a;数据是写在了当前组件中&#xff0c;如有必须&#xff0c;可以使用其中的props传值stepInfos传递相应的数据&#xff0c;根据steps步数就可以控制走到哪一步啦 <temp…

Jave EE 网络原理之应用层与传输层

文章目录 1. 应用层2. 传输层2.1 端口号2.2 UDP协议2.2.1 UDP报文格式2.2.2 UDP的特点 2.3 TCP协议2.3.1 TCP报文格式2.3.2 TCP的相关特性2.3.4 确认应答2.3.5 超时重传2.3.6 连接管理2.3.6.1 TCP三次握手2.3.6.2 四次挥手 2.3.7 滑动窗口2.3.8 流量控制2.3.9 拥塞控制2.3.10 延…

js中将数字转成中文

文章目录 一、实现二、最后 一、实现 如果要将数字10、100和1000转换成中文的"十"、“一百"和"一千”&#xff0c;可以使用以下 JavaScript 代码实现&#xff1a; function numberToChinese(num) {const chineseNums [零, 一, 二, 三, 四, 五, 六, 七, …

MATLAB - 读取双摆杆上的 IMU 数据

系列文章目录 前言 本示例展示了如何从安装在双摆杆上的两个 IMU 传感器生成惯性测量单元 (IMU) 读数。双摆使用 Simscape Multibody™ 进行建模。有关使用 Simscape Multibody™ 构建简易摆的分步示例&#xff0c;请参阅简易摆建模&#xff08;Simscape Multibody&#xff09…

7.3电话号码的字母组合(LC17-M)

算法&#xff1a; 数字到字母要映射&#xff0c;可以用map&#xff0c;也可以用二维数组&#xff0c;或者直接用一个字符串 这里用字符串&#xff0c;键入的数字对应字符串的索引 String[] numString {"", "", "abc", "def", &quo…