OO第二单元博客

news2026/4/29 20:17:15
第二单元 多线程电梯 学习总结报告一、三次作业同步块设置、锁的选择及锁与代码逻辑的关系回顾本单元三次电梯迭代作业我对于锁的概念与使用、临界区保护、线程共享和资源竞争有了完整的实践理解。在整体代码结构中我主要采用对象锁的方式进行并发控制。电梯Elevator类内部全部使用synchronized (this)作为锁。电梯自身的乘客列表、等待请求队列、楼层信息、运行方向、载重数值、电梯运行状态枚举等都是多个线程会并发访问的共享数据。无论是添加外部乘客请求addRequest、接收维修/更新/回收指令还是电梯内部上下客、楼层移动、状态切换全部包裹在同步代码块中。这样设计的原因是每一台电梯都是独立运行的子线程只需要锁住自身实例就能做到细粒度加锁不会出现全局大锁导致线程阻塞等待的问题。这里值得留意的一点是在对于电梯状态进行快照时的读方法不能进行加锁否则会严重影响性能。调度器Dispatcher中针对静态共享集合加锁。全局电梯列表elevators、等待请求缓冲队列waitQueue属于全局共享资源会被输入线程、多个电梯线程同时访问修改。因此在请求分发、等待队列转移、电梯遍历唤醒等操作时都使用集合对象作为锁保证多线程修改队列时不会出现数据覆盖、请求丢失、集合并发报错等问题。当然这里直接使用 Java 中自带的线程安全容器也是可行的。锁与同步块内语句的关联同步块中只存放必须保证原子性的操作例如状态修改、队列增删、数值读写、条件判断修改组合逻辑。而像耗时的Thread.sleep、单纯的逻辑判断、循环遍历不进行写操作等内容尽量放在同步块外面。一方面可以减少锁的持有时间提高整体并发效率另一方面可以避免长时间独占锁造成其他线程大范围阻塞。同时本次作业大量使用wait()和notifyAll()等待唤醒机制而这两个方法必须写在同步块内部。电梯在无任务时会在同步块内循环等待当调度器分配新请求、或者电梯由Normal状态转变为Double状态从而要在换乘层进行避让时就必须唤醒所有等待线程让电梯重新检测任务并继续运行这样既避免空循环浪费资源也保证多线程之间能够正常地协同工作。二、三次作业调度器设计、线程交互与调度策略分析1. 调度器整体设计思路三次作业我全程采用中心化调度器模式由Dispatcher统一管控全部电梯与全部请求。在程序启动时就静态初始化 6 台主电梯与 6 台备用电梯逐个创建独立线程并启动。对于所有外部请求包括普通乘客请求、电梯维修请求、参数更新请求、电梯回收请求全部先交给调度器统一分发处理电梯本身只负责执行运行逻辑不参与请求选择做到调度与执行分离结构更加清晰。2. 调度器与各个线程的交互方式输入线程InputThread持续读取控制台输入识别不同类型请求调用调度器静态分发方法将请求上交调度器处理。输入结束后修改全局标记位并唤醒所有电梯以便电梯线程能够正常结束。调度器Dispatcher作为中间管理层接收输入线程的请求根据每台电梯当前状态、载重、位置、运行方向筛选可用电梯进而选出最优电梯并添加请求当电梯因超载、维修等原因退回请求时调度器负责二次缓存与重新分发同时调度器也参与全局维护剩余请求计数用来判断是否所有请求已全部处理从而判断电梯线程是否应当结束。电梯Elevators持续循环运行被调度器分配任务后执行接人、送客、移动楼层遇到维修、更新、回收指令时主动切换状态清空当前任务并回退请求完成单次任务后主动等待被唤醒后再次判断是否存在新任务。3. 调度策略设计与多性能指标适配本次作业中按照多个指标进行调度分配具有一定启发式性质由于具体权重参数难以确定可能可以通过大量数据对参数进行机器学习但太麻烦了就没有设计具体的代价函数。筛选优先级依次为首先过滤处于不可接收状态的电梯例如正在维修、单双梯模式限制楼层区间的电梯其次优先排除会直接超载的电梯避免了无效的载客替换优先选择当前静止无任务的空闲电梯减少乘客等待时间优先选择运行方向与乘客出行方向一致的顺路电梯减少电梯绕路最后结合电梯当前总负载、距离乘客发起楼层的远近进行综合排序。这套策略可以同时适配多项要求无论在性能还是拓展性方面的表现都较好而且不算复杂我对此较为满意。三、程序运行出现的Bug 及多线程调试方法总结1. 开发过程中遇到的典型bug1多线程数据竞争问题初期设计时因为疏忽没有给个别任务和状态变量加锁多个电梯同时读取修改共享集合偶尔出现乘客请求莫名消失、重复加载同一乘客、电梯列表遍历异常的问题。后期给所有共享资源增加同步保护后该问题完全解决。2线程无法正常结束曾经出现所有任务执行完毕但电梯线程一直卡在wait()无法退出或在请求返回重新分配前就过早结束的问题。原因是对于结束的判断不完善后通过对请求计数待处理和已处理的方法完善了全局结束条件、在其置 0 后统一唤醒全部电梯修复了上述问题。3双电梯换乘楼层死锁在换乘楼层电梯卡死。初始的逻辑是让电梯在Double状态时若在换乘层无任务停靠便自动向临层避让。后来发现其若在Normal状态抵达换乘层停靠则后续切换至Double状态时必须将其唤醒从而解决了死锁问题。4电梯超载问题未在同步块内统计实时载重上下客并发修改重量导致超重判断失效出现超重依旧运行的问题。2. 针对多线程程序的debug方法大量打印关键日志利用题目提供的TimableOutput在电梯到达、开关门、接收请求、状态切换、等待唤醒等关键位置输出信息直观观察每个线程的运行时序和可能出现bug的节点。缩小问题范围遇到并发错误时针对某一特定的特殊场景设计测试用例逐一检查各功能是否存在问题从而减小每次排查的范围。检查所有共享变量养成习惯只要是多个线程都会访问的变量全部检查是否加锁保护从根源避免线程不安全。四、结合三次作业谈谈对线程安全与层次化设计的理解1. 对线程安全的理解经过三次迭代开发我意识到多线程开发最难的地方在于资源竞争与执行时序不可控。线程安全的核心就是多个线程同时操作共享资源时必须通过加锁、限制访问顺序、保证操作原子性来避免数据错乱。所有临界资源都需要主动保护并且想清楚其中的逻辑否则程序就会在不经意之间随机出现各种bug这在现实的工程中是不可接受的且很难调试。同时也要合理控制锁的范围一味地使用大锁虽然安全但是会严重降低并发效率细粒度锁设计十分重要。另外灵活使用多种类型的锁以及线程协作的工具是多线程高效运行的关键能够让多线程按需高效无误地协同运作。2. 对层次化、模块化设计的理解本次代码的分层较为明确输入层InputThread只负责读入数据不处理业务调度层Dispatcher专注请求分配、全局管理执行层Elevator只负责单台电梯运动逻辑工具层FloorUtil、Reclaim提供通用静态方法和业务线程解耦。而在每个层次中尤其是Elevator进一步将不同的执行策略设计成单独的模块。分层设计的优势非常明显每个类职责单一代码可读性高后期迭代新功能时比如电梯的检修、更新和回收只需要在对应层增加代码例如为状态机增加新状态和相应的运行策略不会大范围改动原有逻辑并且在保证原有部分正确的前提下出现bug时可以快速定位模块极大降低多线程程序的调试难度。因此良好的层次化和模块化设计是复杂多线程项目能够稳定迭代的关键。五、大模型使用心得整体项目架构和核心调度策略全部由我自己设计确定主要使用大模型查阅多线程语法并学习锁的使用方法。对我而言依赖大模型范围地生成代码显然是不理智且不太可行的行为我们还是应当时刻保持自己的思考并借助大模型来提升自己学习新知识的效率再在自己的实践中切实巩固所学。六、第二单元学习真实体验与课程建议1. 单元学习体验相比第一单元第二单元对于多线程的学习其实在程序逻辑的复杂度上并没有提高但主要难点在于接触了全新的知识并且更加强调代码编写的严谨性。我从最开始只会简单创建线程、不理解锁的意义到一步步学习临界区、等待唤醒、死锁避免、分层调度三次作业迭代下来收获很大。同时因为运行结果不确定、bug难以复现多线程代码的调试难度远高于单线程整个开发过程需要耐心和严谨的逻辑思维。但相对应的我也在其中学到了很多成长了不少。无论如何还是恭喜自己顺利熬过了这艰难的一个月2. 课程建议首先是编写代码的时间略显不足希望可以适当延长时间期限其次是希望弱测中测能够公开全部样例或者至少公布典型样例为防止特判骗分可以让每个数据点执行特定的测试功能然后生成大量的测试用例在测试时随机选取这样避免了debug时没有头绪浪费大量时间。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…