2026面向对象设计与构造 - 第八次作业

奚烨楠-24373457 2026-04-29 12:05:15

总结分析三次作业中同步块的设置和锁的选择,并分析锁与同步块中处理语句之间的关系

采用了ReentrantLock,每当电梯试图更新自己的状态/更改RequestPool的数据时就要加锁

总结分析三次作业中的调度器设计,并分析调度器如何与程序中的线程进行交互;总结分析三次作业中的调度策略,并分析自己的调度策略是如何适应时间、电量等多个性能指标的

作业中并没有实现具体的调度器

调度策略是这样的:电梯在尝试人员上下、进行移动之前,会分别调用一次DecisionMaker.getInstance().update(this)来更新自己的状态

更新状态时,电梯通过RequestPool获取新的request,步骤如下:

首先对RequestPool加锁,然后遍历RequestPool中的所有乘客请求

对于每个乘客,通过模拟每一部电梯的运动,计算从当前时刻开始,在保留电梯自身与RequestPool的请求,且没有新的输入请求的情况下,哪一个电梯能够最快接到这个乘客,并把这个电梯标记为favoriteElevator

如果favoriteElevator就是电梯本身:1)电梯静止,则立即输出RECEIVE信息,然后去接这个乘客、2)电梯正在运动,则暂时不输出RECEIVE,把这个乘客留在RequestPool,直到电梯恰好能够接上这个乘客,或者电梯送完所有请求进入静止状态,再输出RECEIVE。这个过程中favoriteElelvator可能变成其他电梯

这个调度算法的开销非常大,直接导致了在第二次、第三次作业中的多个数据点出现CPU time limit exceeded,原因如下:

1.乘客会对每一部电梯进行模拟,在客流量较大的时候,一次模拟的计算次数非常多

2.电梯在人员上下、电梯移动前都会尝试从RequestPool里获取新的请求,每次进行这样的操作时,都会对RequestPool里所有的乘客进行更新

3.由于特殊的RECEIVE策略,RequestPool里经常会积压相当数量的请求,在极端数据的情况下,RequestPool里会有60多个乘客请求,而电梯的每次更新都会让所有乘客重新模拟一遍,找出最合适的电梯

分析自己程序出现过的bug以及自己面对多线程程序的debug方法

死锁和轮询是最常出现的bug

最常见的情况就是线程1在持有锁A的时候,尝试去获取锁B,但是锁B已经被线程2占据了,所以线程1阻塞

然后线程2在持有锁B的情况下去获取锁A,因为线程1阻塞了,当然获取不到

最后两个线程就死锁了

解决方法是:尝试获取一把锁之前,先扔掉自己身上的所有锁

轮询出现的原因就是电梯线程休眠/结束的条件没有写全

我的debug方法是在特定位置输出调试信息

debug的难点在于当一个线程出现死锁/轮询时,其他线程还会运行一段时间,并产生新的调试输出,导致很难分辨出到底是哪个线程出了问题

结合三次作业谈谈从线程安全和层次化设计的理解

要实现线程安全主要是考虑是否会出现死锁

我的作业层次化设计做的不太好,因为RequestPool这个类除了负责存储请求外,还有负责电梯的休眠,而电梯的休眠显然让Elevator类本身负责更合适

具体谈谈大模型的使用心得

模型名称:Gemeni

分工:对于一些不清楚的代码细节,问一下AI是怎么回事,以及让AI检查哪里有bug

感受:跟AI对话三轮下来不红温的是这个👍,个人感觉AI不算太好用,也有可能是我的架构设计比较差,有很多地方需要改进

谈谈自己二单元的真实体验和感受

最困难的一个月,好在终于熬过去了

写作业二的时候改bug一直改到凌晨两点半,成功突破个人熬夜记录

建议在作业结束后提供一个示例的代码框架,可以参照这个框架对自己的代码进行修改

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

309

社区成员

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

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