2026 BUAA OO Unit2 总结

刘金奕-24371084 2026-04-25 15:23:21

前言

OO 第二单元的主题是多线程电梯调度。三次作业主要围绕电梯捎带和运行、电梯调度、维修(升级)状态转换展开。

同步和锁

第五次作业

第五次作业中,我的锁集中在 RequestQueue 类中的各个方法。作为“生产者——消费者”模型中的“托盘”,RequestQueue 使用 synchronized 关键字修饰该类中实现的方法,保证对电梯线程的等待队列的增删改查是线程安全的。

任务中涉及到必须调用 Thread.sleep() 的情况时,我将 sleep 写在同步块之外,这样可以尽快释放锁。

第六次作业

第六次作业取消了乘客指定电梯的能力,转而需要我们自行设计调度策略来分配电梯给乘客,追求性能的最大化。

根据解耦的思想,我设计了 ElevatorInfo 类,传递电梯的各种信息(包括它的 RequestQueue)给调度器。调度器据此来计算分数,以分配最优的电梯。通过这种方法,调度器在计算分数时,不需要获取 RequestQueue 的锁,这样就不会阻塞其的操作,提高了并发度。

第七次作业

第七次作业引入了双轿厢电梯,并规定 F2 为换乘层。

我设计了 Shaft 类,并要求同一个电梯井内的两个轿厢若想进入 F2,必须获取 F2 的锁,以避免轿厢发生碰撞。

F2 的锁是主动获取、被动释放的。也就是说当一个轿厢试图进入 F2,必须先提醒电梯井的另一个轿厢:如果另一个轿厢在 F2,其移动一层,并释放 F2 锁。当电梯已经进入 F2 且没有后续动作,它会保持在 F2,直至另一个轿厢唤醒它,便交出 F2 的锁,然后移动一层。

这样做可以最大限度的避免电梯空跑和轿厢相撞。

捎带和调度

捎带策略

三次迭代作业中,我采用的是 LOOK 策略:电梯将一直沿着同一个方向运动,当且仅当轿厢内乘客会在这个方向的某一层下电梯,或是这个方向的某一层有人需要上电梯。

这个策略相比最基础的“一路走到头再折返”而言,可以减少很多电梯空跑的情况,以节约电量,提高性能分。

调度器 DispatchCenter 和调度策略

调度器负责接受输入线程 InputThread 的输入,并维护了 12 个电梯的 RequestQueue 和电梯信息 ElevatorInfo,用于计算分数。

调度器根据计算的分数将乘客放入对应电梯的 RequestQueue 中,并 notify 以唤醒电梯线程。

或者当电梯在未到目标楼层时下客的情况下,将这些乘客重新分配到别的电梯。在这种情况下(比如维修、升级前下客),为了避免重新分配方法中的 wait 拖延时间导致维修(升级)超时,我选择临时开一个新的线程,异步地将这些乘客塞给 DispatchCenter 来重新分配。

对于需要双轿厢情况下需要换乘的请求,我选择分两步进行调度:第一步根据出发楼层调度一个电梯。当电梯运动到换乘层时,下客,并将出发楼层改为 F2,重新分配。

性能

  1. LOOK 算法尽量减少电梯空跑,简约电量。
  2. 在调度电梯时,我自行设计了一个打分机制。它主要考虑电梯到乘客的距离、是否同方向、当前电梯负载等因素,尽量找到一个性能最好的解。但这个打分机制没有经过严谨的数学论证,各个权重是我按照生活经验拟定的(

Bug 和 Debug

没有限制最大负载引发的 Bug

第六次作业中,我虽然将负载作为一个因素引入了计算分数的逻辑中,却没有硬性要求电梯的等待队列不能超过多少人。当五台电梯都在维修时,所有请求都会堆积到剩下的一台,并且无法重新 Receive。这就导致其它电梯维修完成后完全空闲,“一方有难,八方围观”的情况出现()

我在调度方法中限制:如果计算出来的最优电梯已经达到设定的负载上限,就忽略这轮计算,并 Thread.wait(100),再重新求最优电梯。这样就可以避免上述情况的发生。

Debug 方法

多线程无法使用断点调试进行 Debug,因此我选择古法分析:System.out.printf()

对于可能出现 Bug 的地方,我用打印关键变量的方式来观察是否出现 Bug。

此外,我也将任务要求和代码喂给 AI,用 AI 辅助 Debug。

线程安全和层次化设计

线程安全不是靠每一个方法都加入 synchronized 关键字来实现的。关键是理清哪些东西属于是需要进行同步保护的。比如 RequestQueue,它属于典型的“生产者往里面加东西,消费者从里面取东西”的类,这种就需要仔细审查需要 synchronized 的情况。

对于多线程编程,有一个好的层次化设计是非常重要的。ElevatorThread 只管实现电梯的状态机,以及电梯自身的一些方法,比如移动、开关门等。ElevatorCtrl 则负责根据电梯当前的信息进行决策,给电梯返回一个行动指令。这样电梯线程只需要执行指令即可,实现了解耦。

DispatchCenter 是整个系统的大脑,也是一个中转站,负责把输入解析并给到对应的类中处理。这也是层次化设计的一个体现。

大模型的使用

本单元中,我使用的主要是 Gemini 和 Google AI Studio 的 Gemini 模型。均为网页对话,没有使用 Agentic Coding。我认为网页对话可以在某种程度上限制我对 AI 的使用,尽量只与其交流思路和框架,以及代码纠错。用 Agent 可能会不知不觉中用 Tab 写完了整个代码(

个人感受和建议

第二单元对我而言是第一次接触多线程编程,我认为很有价值。实验课的代码给我们提供了很好的框架和思路,但是感觉引导略有不足。

我的建议是:

  1. 增加多线程的介绍和讲解,可以像 OOPre 那样在每次作业指导书提供一些提示。但考虑到指导书本身篇幅很长,我觉得这还需要进一步考虑。
  2. 提供一个输出检查器。多线程程序的输出使用瞪眼法检查正误难度太大()既然互测提交数据时会检查输出是否正确,我认为这个检查可以在互测前公开给大家使用,感觉并不会引发什么问题🤔
...全文
58 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
代码下载链接: https://pan.quark.cn/s/a8fbca3925b4 《鸿蒙OS开发环境构建》指南系统性地阐述了配置和筹备鸿蒙OS开发所需的各种工具和条件的具体方法。鸿蒙OS,亦称HarmonyOS,是由华为研发的一款面向全场景的分布式操作系统,其目标是提供跨平台、多设备间无缝协作的使用体验。本指南涉及了从Linux服务器到Windows工作站的完整开发流程。指南中提及了MobaXterm,这是一款用于连接Linux源码服务器的软件,使得开发人员能够在Windows环境中远程访问Linux服务器。同时,HiTool作为烧录工具,用于将编译后的系统镜像写入开发板。IPOP.EXE则是一款串口终端软件,用于执行串行通信和调试任务。Embedded Studio用于开发设备驱动程序,而DevEco Studio是华为提供的图形化应用程序开发平台,支持C/C++语言,拥有代码编辑、编译、烧录和调试功能,被视为OpenHarmony智能设备开发者的首选集成开发环境。在硬件配置方面,指南列出了必需的设备,包括Linux服务器(推荐Ubuntu 16.04及以上版本),Windows工作台(兼容XP/7/10),以及Hi3518EV300 IoT Camera单板。开发期间,Windows工作台通过USB线与单板相连接,以实现数据传输。此外,为了开展开发工作,还需要安装putty、IPOP、tftp服务器等辅助软件,以及HiTool用于烧录操作。在软件系统要求方面,Linux服务器需要安装bash、Python3.7+、gn、ninja、LLVM等构建工具,这些工具对于生成和执行编译脚本具有关键作用。在Windows工作台上,建议采用Visual Studi...

309

社区成员

发帖
与我相关
我的任务
社区描述
2026年北航面向对象设计与构造
java 高校
社区管理员
  • 孙琦航
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧