北航OO第二单元多线程电梯作业总结博客

沈钡-24373462 2026-04-29 23:10:09

北航OO第二单元多线程电梯作业总结博客

一、三次作业同步块设置与锁选择分析

本单元电梯作业核心是多线程安全协作,三次作业迭代中,我围绕wait/notifyReentrantLocksynchronized三种同步机制,逐步优化锁粒度与同步块逻辑,保证线程安全且避免轮询、死锁。

1. 同步块(synchronized)使用场景

  • 电梯井状态机同步ElevatorShaft中状态切换、紧急请求接收(检修 / 改造 / 回收)均用synchronized (this)包裹,保证状态原子性修改与wait/notify安全唤醒。

  • 电梯线程等待唤醒Elevator run () 方法中,用synchronized (this)包裹等待条件判断,避免多线程同时修改emergencyStopisWaiting等状态。

  • 调度器请求分发SchedulerdispatchRequestreDispatchRequestssynchronized,防止多线程同时分配请求导致重复 RECEIVE。

2. 显式锁(ReentrantLock)使用场景

  • 电梯移动互斥ElevatormoveLock保护电梯移动逻辑,避免双轿厢模式下两部电梯同时修改楼层、触发碰撞。

  • 电梯开关门互斥operationLock保证开门、关门、乘客进出的原子性,满足 “开门至少 0.4s” 的约束。

  • 请求队列安全RequestQueueReentrantLock+Condition实现生产者 - 消费者,替代synchronized,更灵活控制等待与唤醒。

3. 锁与同步块内语句的关系

  • 锁粒度最小化:同步块仅包裹共享变量读写原子操作,不包裹Thread.sleep()、电梯移动等耗时操作,避免长期占锁导致性能下降。

  • wait/notify 必须在同步块内:所有wait()notify()均在synchronized内部,防止IllegalMonitorStateException

  • 共享变量必须加锁:电梯楼层、乘客队列、状态机状态等全局共享数据,读写必加锁,保证多线程可见性与原子性。

  • 避免嵌套锁死锁:严格控制锁的获取顺序,如先锁电梯井、再锁电梯对象,不循环依赖锁。


二、调度器设计、线程交互与调度策略分析

1. 三次作业调度器设计迭代

  • 第五次作业:无智能调度,仅按输入指定电梯分发请求,调度器为 “空壳转发器”。

  • 第六次作业:新增检修请求,调度器增加电梯可用性判断,检修中的电梯不分配请求。

  • 第七次作业:支持双轿厢改造 / 回收,调度器新增电梯井可用轿厢筛选,根据乘客起终点分配主轿厢 / 备用轿厢。

最终架构:Scheduler作为中央调度器,持有全部电梯井引用,统一接收乘客请求,按策略分配到最优电梯。

2. 调度器与线程的交互

  • 输入线程→调度器InputThread读取输入,将乘客请求交给dispatchRequest,紧急请求直接发给对应电梯井。

  • 调度器→电梯线程:调度器选中最优电梯后,调用addRequest加入队列,并notifyAll()唤醒等待的电梯线程。

  • 电梯线程→调度器:电梯检修 / 改造 / 回收时,清空未完成请求,调用reDispatchRequests交回调度器重新分配。

  • 状态机→调度器:电梯井状态切换完成后,调用reDispatchPendingRequests分配暂存请求。

3. 调度策略与性能适配

我的核心调度策略:负载优先 + 距离最优评分公式

score = 电梯总请求数 × 3 + 电梯当前楼层到起点楼层距离
  • 适配时间指标:优先分配负载低、距离近的电梯,减少电梯空跑、缩短乘客等待时间,降低总运行时间。

  • 适配电量指标:减少不必要的 ARRIVE、OPEN、CLOSE,降低移动层数与开关门次数,节约耗电量。

  • 双轿厢适配getAvailableCars按楼层范围分配,主轿厢服务 F2-F7,备用轿厢服务 B4-F2,避免跨范围无效分配。

  • 紧急场景适配:检修 / 改造 / 回收时,自动释放请求并重新调度,不阻塞整体流程。


三、多线程 Bug 与 Debug 方法总结

1. 典型 Bug 复盘

  1. 轮询 CPU 超标:初期用while(true)空转判断队列是否为空,CPU 时间超 10s。
    修复:改用wait/notify,无任务时线程休眠,不占用 CPU。

  2. 死锁:嵌套获取电梯锁与电梯井锁,顺序不一致导致循环等待。
    修复:统一锁获取顺序,先锁电梯井,再锁电梯对象。

  3. 重复 RECEIVE:多线程同时分配同一乘客,输出多条 RECEIVE。
    修复:PassengerManager标记乘客接收状态,调度器加synchronized

  4. 双轿厢碰撞:两部电梯同时到达 F2,违反 “不同时同层” 约束。
    修复:isCollisionPossible判断冲突,强制一部电梯避让。

  5. 线程无法退出:请求结束后电梯线程仍在wait(),程序不结束。
    修复:RequestCounter计数为 0 时,唤醒所有电梯线程。

2. 多线程 Debug 方法

  1. 日志定位:用TimableOutput输出关键状态(锁获取 / 释放、wait/notify、状态切换),还原线程执行顺序。

  2. 单线程调试:先关闭多线程,用单线程跑通逻辑,再逐步开启并发。

  3. 查看线程状态:用 IDEA 调试工具查看线程是否阻塞、死锁、等待。

  4. 最小化复现:用简单用例复现 Bug,避免复杂数据干扰。

  5. 共享变量检查:所有共享变量必须加锁,逐行检查是否有线程不安全读写。


四、线程安全与层次化设计理解

1. 线程安全理解

线程安全不是 “加锁越多越好”,而是合理控制共享资源访问

  • 原子性:一系列操作要么全部完成,要么不执行,用锁保证。

  • 可见性:一个线程修改共享变量,其他线程能立即看到,用synchronizedvolatile保证。

  • 有序性:避免指令重排导致逻辑错误。
    本单元中,乘客队列、电梯状态、状态机状态是核心共享资源,全部用锁严格保护。

2. 层次化设计理解

我采用四层架构,层次清晰、易于迭代:

  1. 输入层InputThread读取输入,分发请求。

  2. 调度层Scheduler统一分配请求,协调全局资源。

  3. 电梯井层ElevatorShaft管理状态机,控制主 / 备用轿厢。

  4. 电梯层Elevator执行开关门、移动、乘客接送。

优势:

  • 职责单一:每层只做一件事,便于修改与维护。

  • 迭代友好:第六次加检修、第七次加双轿厢,只需修改对应层,不影响整体架构。

  • 线程隔离:每层线程独立通信,通过方法调用交互,降低耦合。


五、大模型使用心得(重点)

1. 模型名称

主要使用豆包deepseeklingma完成本单元作业。

2. 我与大模型的分工

  • 我负责:整体架构设计、锁与同步块规划、调度策略制定、Bug 定位与修复、代码逻辑验收。

  • 大模型负责

    1. 多线程语法规范检查,提示wait/notifyReentrantLock使用细节。

    2. 生成模板代码,如RequestQueuePassengerManager等工具类。

    3. 解释死锁、轮询、可见性等多线程概念,辅助理解原理。

    4. 快速生成状态机、调度逻辑的伪代码,提高编码效率。

3. 大模型在多线程电梯中的优势

  • 快速查漏补缺:能精准指出锁遗漏、同步块错误、wait/notify位置不当等问题。

  • 多线程概念讲解直观:用通俗语言解释复杂理论,降低学习门槛。

  • 代码生成效率高:工具类、枚举、状态机框架可一键生成,节省重复编码时间。

  • Debug 辅助:根据报错信息与代码片段,快速定位线程安全问题。

4. 大模型遇到的困难

  • 无法完全理解作业细节约束(如 RECEIVE 规则、双轿厢楼层限制、检修时间约束)。

  • 复杂调度策略需要人工调整,模型生成的策略难以直接满足性能要求。

  • 多线程 Bug 复现环境复杂,模型只能给出通用思路,无法精准复现现场。

5. 使用感受

大模型是高效辅助工具,不是 “代做工具”。在多线程这种强逻辑、强规范的作业中,模型能帮我节省大量时间,但架构设计、策略优化、Bug 修复必须靠自己思考。使用模型后,我更专注于设计与逻辑,而非语法与细节拼写,学习效率大幅提升。


六、第二单元真实体验与建议

1. 真实体验

第二单元是 OO 课程难度跃迁的单元,从单线程直接进入多线程,初期被死锁、轮询、线程安全搞得很崩溃。但随着三次作业迭代,逐步理解了锁、线程协作、层次化设计的思想,最终写出稳定、高效的电梯程序,成就感很强。
多线程编程的核心是 控制共享,所有问题都源于资源竞争,所有解决方案都围绕 “有序访问” 展开。

2. 对课程的建议

  1. 增加多线程基础实验:在第五次作业前,增加简单的生产者 - 消费者小实验,降低入门难度。

  2. 提供锁与同步块示例:官方给出标准的线程安全队列、等待唤醒模板,减少学生踩坑。

  3. 性能指标说明更清晰:提前明确时间、电量的计算方式与优化方向。

  4. 多线程 Debug 教学:增加专门的 Debug 讲座,讲解日志、线程监控、死锁排查方法。

非常感谢课程组的设计,第二单元让我真正掌握了多线程编程的核心能力,收获极大!

...全文
35 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

304

社区成员

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

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