oo第二单元总结报告

杜瑞-22230613 学生 2024-04-20 15:48:50

一、 最终的uml类图如下

img


其中出现的继承了elevator类的elevatorA与elevatorB分别代表电梯进行双轿厢重置后得到的两个新电梯,其中elevatorA只在下层及交换楼层活动,elevatorB只在上层及交换电梯活动。

二、同步块与锁的处理

锁的处理是本单元作业的重点之一,在本作业中我基本还是采用的synchronized类型的锁,主要用于set系列等可能会引起多线程违背原子法则的方法中以确保原子法则。

三、调度器与调度策略

为了实现电梯与调度类的协调,我在实现电梯运行的的elevator类中设置了addPassenger等用于添加乘客请求的方法,以便schedule类在读到请求时能将请求分配到对应id的电梯中。对于调度策略,由于本人的能力问题,我没能使用很多同学所采用的“影子电梯”,而是采用了较为简单的轮转分配法(即将请求按照id轮流分给每个电梯)。这样的分配方法导致我的综合得分并不是很理想。而对于时间上的问题,最多的还是出现对于wait指令的不恰当使用而导致不少电梯处于空转(即没有乘客请求的电梯对应的线程仍在运行)或者死锁(即部分电梯陷入wait状态而无法脱离),考虑到这点,我在设计elevator类中唯一的wait的条件时将条件设置为电梯内没有请求(即存放request的数组为空)且读取还未结束(调度器还未读取到null),这样的设计在前两次作业还能正常使用,但在第三次作业中出现了较为明显的问题,这一点放在后面的bug处理再讲述。

四、实现双轿厢的不碰撞

关于双轿厢的不碰撞问题,我采用的是在评论区的一位同学的思路上进行了部分个人的改造。那位同学的思路是设置一个由elevatorA与elevatorB共用的变量occupied,当occupied为1表示交换楼层被占用,occupied为0表示交换楼层处于空置状态。但由于我个人的代码中在给电梯添加乘客请求时便会根据occupied变量进行对occupied的修改及对目标楼层的确认(即电梯不能超过自己的活动区域),所以有时候可能会出现occupied为1时并不能确认是由哪方占据了进入交换楼层的可能。故而我在此基础上修改了部分规则,即规定occupied为1表示A电梯有权力进入交换楼层,而occupied为2则表示B电梯有权力进入交换楼层,任何一方在进入交换楼层并完成对应的送客、接客人物后会额外移动一层以脱离交换楼层,同时将occupied设置为0并唤醒另一部电梯。

五、出现的bug及修复

本次作业的实现中出现了不少bug,主要分为部分电梯未在需要wait的情况下仍然运行导致CPU超时与电梯出于某些原因一直处于wait而未被唤醒导致real time exceed两种。其中我最为印象深刻的是在第三次作业中可能出现的一种双轿厢电梯死锁现象:假设A电梯拿到了前往交换楼层的机会并在交换楼层接到乘客后离开,而此时B电梯的主请求也需要前往交换楼层,故需要B电梯处于wait状态,而A电梯在送完人后由于B电梯内仍存在请求而并不能结束进程同样进入wait状态,最终导致两部电梯互相锁住,解决办法是在电梯于交换楼层中接到人并离开就重新将occupied设置为0(即提前修改occupied的时间),这样就不会出现上述所说的互相锁住对方的问题了。
对于多线程的debug问题,由于多线程不允许像之前作业一样调试,故大多数检测bug都是通过采用新增输出各变量的语句来鉴别异常出现的位置,这种办法相比于之前的调试麻烦了不少,但也属于无可奈何的问题了。

六、心得体会

本次多线程的作业相比于上一单元的多项式难度明显提升了不少,无论是同步锁、对电梯的构造还是多个线程的sleep、wait与notifyall等明显比之前更具挑战性,同时也更贴合现实生活了,因此我也是收获匪浅,希望在之后的两个单元中我也能够像这个单元一样更好地提升自己。

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

301

社区成员

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

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