BUAA-OO-U2-Summary

BUAA-OO-U2-Summary

1 问题描述

本单元任务主要是实现一个多线程的电梯调度系统。

实际场景是BUAA新主楼的 A B C D E 五个座,每个座均有10层,楼座按顺序构成一个环;

其间存在两种电梯:横向(同一层,不同座间移动) 和 纵向(同一座,不同层间移动),电梯的移动速度,载客量,可达楼座等参数可设置;

对于每个乘客,会在某一时刻进入等待队列,表明自己的出发楼层和楼座以及目的楼层和楼座,等待电梯承载;

输入的命令有两种:添加电梯添加乘客 ,提供足够的信息;

目标是把每个乘客从出发位置载至目的位置,尽量让时间最短。

2 整体结构

本单元的实验中,采用以下结构进行调度:

其中,allocator 主要进行请求的拉取和乘客、电梯的分配操作;

Elevator 主要进行电梯当前状态与参数的存储、从当前座/层的等待队列中拉取和释放乘客,仍需换乘的乘客丢回 allocator 继续处理;

Advisor 是每个电梯拥有一个、根据当前电梯和电梯所在VisitorQueue的状态对电梯行为进行控制的模块;

VisitorQueue 共15个,10层+5座 各有一个,是主要的synchronized块;

Output是为了保证输出线程安全的synchronized块。

各部分协作图如下:

3 捎带策略

捎带策略有纵向和横向电梯之分:

对于纵向电梯,采用LOOK算法,即向一个方向移动至最远的请求或目的地,中途接取同方向的请求,前方无请求时,调转方向继续移动。

对于横向电梯,由于楼座仅五个且构成环,因此直接进行单方向的循环移动,接取沿途所有的乘客。

对于需要进行换乘的乘客,在allocator内进行路线判断:

  1. 寻找最近的可以到达目标楼座的楼层,将乘客下一地点定为该楼层并放入该楼座的纵向等待队列中;
  2. 若本层即可到达目标楼座,将乘客下一地点定为目标楼座并放入该层的横向等待队列中;
  3. 若当前楼座即为目标楼座,将乘客下一地点定为目标楼层并放入该座的纵向等待队列中。

4 迭代过程

三次迭代中,调度系统的整体结构没有变化,主要变化在于:

  1. 新增增加电梯的请求;
  2. 新增换乘判断逻辑;
  3. 新增电梯参数的自定义初始化。

5 强测总结

三次强测中,第三次强测出了意外情况:增加电梯可达楼座的情况下,Advisor中有一处是否接取乘客的判断没有修改,导致横向电梯出现接取不该接取乘客,该乘客也无法出门(电梯吃人)的情况。

6 互测总结

互测中,前两次均未出现bug,第三次互测中由于上述bug被hack得很惨;

除此之外,还有等待队列中由于notifyAll的滥用,导致当前队列没有乘客时,两个电梯互相notify,导致CPU时间爆炸的情况。

7 个人总结

本单元个人认为最大的问题在于迭代时没有进行修改汇总,导致修改遗漏的出现,以后要多注意这一点。

posted @ 2022-04-30 17:47  Fixed丨  阅读(37)  评论(0编辑  收藏  举报