4.23学习总结

一.NIO(一)

(一).简介:

NIO 是 Java SE 1.4 引入的一组新的 I/O 相关的 API,它提供了非阻塞式 I/O、选择器、通道、缓冲区等新的概念和机制。相比与传统的 I/O 多出的 N 不是单纯的 New,更多的是代表了 Non-blocking 非阻塞,NIO具有更高的并发性、可扩展性以及更少的资源消耗等优点。

(二).NIO 与传统BIO:

NIO:是同步非阻塞的,服务器实现模式为 一个线程处理多个连接。服务端只会创建一个线程负责管理Selector(多路复用器),Selector(多路复用器)不断的轮询注册其上的Channel(通道)中的 I/O 事件,并将监听到的事件进行相应的处理。每个客户端与服务端建立连接时会创建一个 SocketChannel 通道,通过 SocketChannel 进行数据交互。

BIO:全称是Blocking IO,同步阻塞式IO,是JDK1.4之前的传统IO模型,服务器实现模式为一个连接一个线程。每当客户端有连接请求时服务器端就需要启动一个线程进行处理。

两者主要区别如下:

  • 阻塞和非阻塞:NIO 使用非阻塞式 I/O,而 BIO 使用阻塞式 I/O。在阻塞式 I/O 中,当一个 I/O 操作完成之前,线程会一直被阻塞,直到 I/O 操作完成;在非阻塞式 I/O 中,线程可以继续执行其他任务,直到 I/O 操作完成并返回结果。
  • 线程模型:NIO 中的线程模型是基于事件驱动的,当一个 I/O 操作完成时,会触发相应的事件通知线程处理;而在 BIO 中,每个线程都负责处理一个客户端连接,需要不断地轮询客户端的输入输出流,以便及时响应客户端的请求。
  • 内存消耗:NIO 中使用的缓冲区(Buffer)可以重复利用,减少了频繁的内存分配和回收,从而减少了内存的消耗;而在 BIO 中,每个客户端连接都需要单独分配一个缓冲区,容易造成内存的浪费。
  • 并发性能:NIO 中使用非阻塞式 I/O,可以同时处理多个客户端连接,从而提高了并发处理能力;而在 BIO 中,由于每个客户端连接都需要一个线程来处理,当连接数量增加时,容易出现线程饥饿和资源耗尽的问题。

 

(三).NIO的核心原理

 

 工作流程:

  • 创建 Selector:Selector 是 NIO 的核心组件之一,它可以同时监听多个通道上的 I/O 事件,并且可以通过 select() 方法等待事件的发生。
  • 注册 Channel:通过 Channel 的 register() 方法将 Channel 注册到 Selector 上,这样 Selector 就可以监听 Channel 上的 I/O 事件。
  • 等待事件:调用 Selector 的 select() 方法等待事件的发生,当有事件发生时,Selector 就会通知相应的线程进行处理。
  • 处理事件:根据不同的事件类型,调用对应的处理逻辑。
  • 关闭 Channel:当 Channel 不再需要使用时,需要调用 Channel 的 close() 方法关闭 Channel,同时也需要调用 Buffer 的 clear() 方法清空 Buffer 中的数据,以释放内存资源。

 

 二.java聊天室控制台实现公聊私聊

其私聊核心思路就是hashmap将每个人的id(用户名)和其对应的输出流,形成键值对,存到hashmap中,在需要的时候,直接根据用户名就可以调出其对应的输出流.

公聊的核心思路在于使用ArrayList集合,将所有用户的输出流都存入集合中,然后遍历对每个用户进行输出.

实例代码:

客户端:

public class Client {public static void main(String[] args) {//连接服务器try {System.out.println("连接服务端");Socket socket = new Socket("localhost",8088);System.out.println("连接服务端成功");Thread t1 = new Thread(new ClientWriteData(socket));Thread t2 = new Thread(new ClientReadData(socket));t1.start();t2.start();} catch (IOException e) {e.printStackTrace();}}
}
class ClientWriteData implements Runnable{private Scanner scan;private Socket socket;public ClientWriteData(Socket socket){this.socket = socket;}public void run(){try {OutputStream out = socket.getOutputStream();OutputStreamWriter osw;osw = new OutputStreamWriter(out,"GBK");PrintWriter pw = new PrintWriter(osw,true);System.out.println("请输入用户名:");scan = new Scanner(System.in);String str0 = scan.next();pw.println(str0);while(true){System.out.println("请选择私聊或者群发:1表示私聊\t2表示群发");int n = scan.nextInt();pw.println(n);switch(n){case 1:System.out.println("请输入私聊对象: ");String name = scan.next();pw.println(name);System.out.println("私聊的信息:");String str = scan.next();pw.println(str);break;case 2:System.out.println("请输入群发消息:");System.out.println(str0+"正在发消息:");String str1 = scan.next();pw.println(str1);break;default:System.out.println("退出消息发送:");System.exit(0);}}} catch (IOException e) {e.printStackTrace();}}
}
class ClientReadData implements Runnable{private Socket socket;public ClientReadData(Socket socket){this.socket = socket;}public void run(){try {InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is,"GBK");BufferedReader br = new BufferedReader(isr);String str = null;while((str = br.readLine())!=null){System.out.println(str);}} catch (IOException e) {System.err.println("服务端已断开!!!");e.printStackTrace();}}
}

服务端:

public class Server {//群发//定义一个集合,用于存储所有客户端的输出流List<PrintWriter> allPw = new ArrayList<>();//用于根据用户名存储客户端输出流Map<String,PrintWriter> map = new HashMap();//创建线程池对象//ExecutorService pool = Executors.newCachedThreadPool();public static void main(String[] args) {try {//向系统申请端口号 端口号是系统中所有程序没有使用过的端口,才能使用成功//端口号的范围:0-65535之间 0-1023之间是系统端口ServerSocket server = new ServerSocket(8088);System.out.println("服务端开启成功!!!");Server s = new Server();while(true){System.out.println("等待客户端连接:");//阻塞方法 accept():等待客户端的连接Socket accept = server.accept();System.out.println("和客户端连接成功!!!");//获取IP地址InetAddress address = accept.getInetAddress();String ip = address.getHostAddress();System.out.println(ip);Thread t = new Thread(s.new ClientHandler(accept));t.start();}} catch (IOException e) {e.printStackTrace();}}class ClientHandler implements Runnable{private Socket socket;public ClientHandler(Socket socket){this.socket = socket;}public void run(){try{InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is,"GBK");BufferedReader br = new BufferedReader(isr);OutputStream os = socket.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(os,"GBK");PrintWriter pw = new PrintWriter(osw,true);//一个客户端连接服务器,则把输出流存入到集合中String str = null;//用户名String name = br.readLine();allPw.add(pw);map.put(name, pw);while((str = br.readLine())!=null){if(str.equals("1")){//私聊工作//需要私聊的对象str = br.readLine();//私聊对象的输出流PrintWriter p = map.get(str);str = br.readLine();p.println(str);}else{//群发System.out.println("");str = br.readLine();for(PrintWriter p:allPw){if(p == pw){continue;}p.println(str);}}}}catch(IOException e){e.printStackTrace();}}}
}

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

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

相关文章

OKCC搭建配置什么样的服务器合适

OKCC呼叫中心系统是一种采用软硬件结合的架构方式、及分布式的IP技术&#xff0c;从多角度为企业提供整合的一体化解决方案。因此&#xff0c;搭建OKCC呼叫中心系统所使用的服务器应该满足以下几点要求&#xff1a; 稳定性&#xff1a;服务器需要具有较高的稳定性和可靠性&…

JavaSE——程序逻辑控制

1. 顺序结构 顺序结构 比较简单&#xff0c;按照代码书写的顺序一行一行执行。 例如&#xff1a; public static void main(String[] args) {System.out.println(111);System.out.println(222);System.out.println(333);} 运行结果如下&#xff1a; 如果调整代码的书写顺序 , …

2024华中杯A题|太阳能路灯光伏板的朝向设计问题(思路、代码.....)

太阳能路灯由太阳能电池板组件部分(包括支架)、LED灯头、控制箱(包含控制器、蓄电池)、市电辅助器和灯杆几部分构成。太阳能电池板通过支架固定在灯杆上端。太阳能电池板也叫光伏板,它利用光伏效应接收太阳辐射能并转化为电能输出,经过充放电控制器储存在蓄电池中。太阳能…

Midjourney-01 初试上手 注册使用并生成你的第一张AI图片 详细流程 提示词 过程截图 生成结果 付费文生图的天花板!

背景介绍 Midjourney是一款基于人工智能技术的绘画软件&#xff0c;利用深度学习算法来辅助用户进行绘画创作。这款软件能够通过用户输入的文本描述生成图像&#xff0c;支持多种生成方式&#xff0c;包括文字生成图片、图片生成图片和混合图片生成图片。 图像生成方式&#…

开发区块链DApp应用,引领数字经济新潮流

随着区块链技术的飞速发展&#xff0c;分布式应用&#xff08;DApp&#xff09;正成为数字经济中的一股强劲力量。DApp以其去中心化、透明公正的特点&#xff0c;为用户带来了全新的数字体验&#xff0c;开创了数字经济的新潮流。作为一家专业的区块链DApp应用开发公司&#xf…

软件项目经理需要具备这 11 个能力

当前软件开发技术更新换代越来越快&#xff0c;各种项目实施管理思想也日新月异&#xff0c;作为一个软件项目经理&#xff0c;需要具备这 11 种能力&#xff1a; 1. 项目管理能力 了解项目管理的基本原则和方法&#xff0c;包括制定项目计划、资源分配、风险管理、问题解决和…

出海不出局 | 小游戏引爆高线市场,新竞争态势下的应用出海攻略

出海小游戏&#xff0c;出息了&#xff01; 根据 Sensor Tower 近期发布的“2024 年 3 月中国手游收入 TOP30”榜单&#xff0c;出海小游戏在榜单中成了亮眼的存在。 其中&#xff0c;《菇勇者传说》3 月海外收入环比增长 63%&#xff0c;斩获出海手游收入增长冠军&#xff0c…

IUG-CF论文精读

Neural collaborative filtering with ideal user group labels &#xff08;具有理想用户组标签的神经协同过滤&#xff09; 论文地址&#xff1a;https://www.sciencedirect.com/science/article/pii/S0957417423023898 摘要&#xff1a; 人口统计信息是推荐系统(RSs)的关键…

Mysql用语句创建表/插入列【示例】

一、 创建表 COMMENT表示字段或列的注释 -- 新建student表 CREATE TABLE student (id BIGINT NOT NULL COMMENT 学生id, enroll_date DATE NOT NULL COMMENT 注册时间, NAME VARCHAR(18) DEFAULT NOT NULL COMMENT 学生姓名, deal_flag TINYINT(1) DEFAULT 0 NOT NULL COMM…

TLV61048非同步升压BOOST转换器输入电压2.6-5.5V输出电流4A输出电压最高15V

推荐原因&#xff1a; 输入电压较低&#xff0c;输出电流可达3.5A SOT23-6封装 批量价格约0.70元 TLV61048引脚 TLV61048引脚功能 7 详细说明 7.1 概述 TLV61048是一款非同步升压转换器&#xff0c;支持高达 15 V 的输出电压和输入范围从 2.61 V 到 5.5 V。该TLV61048集成了…

Nacos配置中心动态刷新原理

三种模式&#xff1a; ①&#xff1a;pull模式&#xff1a;主动拉去配置&#xff0c;通过固定的时间间隔。缺点&#xff1a;频繁请求&#xff0c;时效性不高&#xff0c;时间间隔不好设置。 ②&#xff1a;push模式&#xff1a;服务端检测到变化&#xff0c;主动将新配置推送给…

Atlas Vector Search:借助语义搜索和 AI 针对任何类型的数据构建智能应用

Atlas Vector Search已正式上线&#xff01; Vector Search&#xff08;向量搜索&#xff09;现在支持生产工作负载&#xff0c;开发者可以继续构建由语义搜索和生成式人工智能驱动的智能应用&#xff0c;同时通过 Search Node&#xff08;搜索节点&#xff09;优化资源消耗并…

http 3.0 有哪些新特性

HTTP/3 是超文本传输协议&#xff08;HTTP&#xff09;的最新主要版本&#xff0c;其显著特点是放弃了传统的TCP作为传输层协议&#xff0c;转而采用基于UDP的QUIC&#xff08;Quick UDP Internet Connections&#xff09;协议。以下是HTTP/3利用QUIC实现高性能传输的关键特性&…

简单的图像处理算法

基础&#xff1a;图像处理都是用卷积矩阵对图像卷积计算&#xff0c;如3X3 的矩阵对640 X 480分辨率的图像卷积&#xff0c;最终会得到638 X 478 的图像。卷积过程是这样的&#xff1a; 一、中值滤波 &#xff1a; 找出矩阵中的最中间值作为像素点 二、均值滤波&#xff1a;找…

作为面试官,我在面试产品经理时,重点考察的5个能力

以往的面试经验&#xff0c;都是从打工人的角度去谈该如何准备&#xff1b;少有人从面试官角度去分析为什么会这样。这篇文章&#xff0c;作者从面试官角度出发&#xff0c;直接告诉大家&#xff0c;他考察的&#xff0c;会是这几个方面的问题。 最近在招聘面试产品经理&#x…

第三章、汇编1

编译选项知识 -Og&#xff1a;这是 GCC 和 Clang 编译器提供的优化选项之一。-Og 的含义是“优化级别为 g”&#xff0c;其中的 “g” 代表了"g优化"。这个选项的作用是启用一些基本的优化&#xff0c;以尽量保持生成的代码易读易调试。它通常会保留变量名和源代码结…

Idea如何本地调试线上测试服务器代码?

线上出现问题&#xff0c;但是没加日志打印拍脑门惋惜为啥不多打一行日志 加日志重新部署&#xff0c;半小时没了&#xff0c;问题还没有找到&#xff0c;头顶的灯却早已照亮了整层楼...... 排查别人线上的 bug&#xff0c;不仅代码还没看懂&#xff0c;还没一行日志&#…

Linux:目录目录、文件管理

Linux&#xff1a;目录、文件管理 文件系统 Linux 系统中的所有文件存储在文件系统中&#xff0c;它们被组织到一个颠倒的目录树中&#xff0c;称为文件系统层次结构。这棵树是颠倒的&#xff0c;因为树根在该层次结构的顶部&#xff0c;树根的下方延伸出目录和子目录的分支。…

高级控件3:ViewPager

ViewPager&#xff1a;翻页视图&#xff0c;可以在水平方向上滑动。常用于做欢迎页、图片轮播、标签页等场景一个页面View就是一个数据条目&#xff08;可以理解为一个子项&#xff09;适配器&#xff1a;PagerAdapter&#xff0c;该接口有两个子类&#xff0c;FragmentPagerAd…

【Linux】理解文件系统——那就浅聊一下吧

前言 在上一篇文件描述符详解中谈论的都是打开的文件&#xff0c;但是在我们的系统中不仅有打开的文件还有许多未打开的文件&#xff0c;那么这些未打开的文件又该如何理解呢?阅读完本篇文章相信你会得到答案。 如果觉得文章内容对你有所帮助的话&#xff0c;可以给博主一键三…