301
社区成员
发帖
与我相关
我的任务
分享第二单元主要通过多线程来实现多部电梯系统,其中核心的内容有:

在电梯中依据scan算法写了一个请求排序算法,用以让电梯从当前所有的请求中识别主任务,也就是捎带,这也是第一次作业主要的内容,由于第一次作业指定了完成请求的电梯,所以只需考虑输入请求序列未完成,电梯无请求时的wait()处理和添加请求时唤醒处理notifyAll()。
第二次作业取消了第一次作业中指定电梯完成请求的设定,以及添加了重置设定,在此就需要编写相应的分配请求策略,在这次的作业中我延用了第一次作业所写的scan算法,根据路径来分配请求。一开始的想法是将请求分配给最靠近请求的电梯。后来发现电梯最靠近请求并不代表能最有效率的完成请求,于是就又想到了工作时长的办法,计算电梯完成请求的耗时,并选择耗时最短的电梯来分配。
另外,关于reset的设定,reset的请求相比乘客请求有着更高优先级,即一堆乘客请求和reset请求同一时间发出时,需要优先处理reset请求。在这里我一开始是将两种请求统一处理,即两者优先级相同,并且调度器会判断当前运行中电梯是否满人,如果满人则等待电梯空出位置后再分配请求。在此就导致了一个bug,当一组超过所有电梯容量的乘客请求和reset请求一起发出时,在输入时间上他们是一样的,但是reset排在乘客请求之后,这样就导致reset请求无法第一时间被处理,会和乘客请求一起排队。
在和研讨课的同学交流后,以及通过自己思考,目前有着两种解决方案。若是为了完成作业,同学所说的方法会更好些(更容易实现,也不怎么会导致bug)就是给每个电梯设置请求池,即使是重置状态,依旧分配请求,但是电梯不处理请求,直到重置状态结束,才开始receive被分配的任务。但是考虑到现实中若电梯需要维修,维修时长并非一直可知,于是我尝试了另一种办法,就是把乘客请求和重置请求分开调度,也就是类图中的personRequestController和resetRequestController,这个办法确实保证了重置请求能不被干扰地让电梯接受,在bug修复中也证实解决了这个问题,可是可能一些线程上面的管理没处理好,到最后依旧有一个样例rtle。
另外就是电梯系统的监听者模式observer,个人认为这个还是比较重要的,在规模较大的系统中,可以有一个类专门负责搜集各个部分的状态变化,而调度器则可以直接根据observer实例中的数据获得系统中各个模块的状态,并按照已有的调度策略进行调度。
第三次作业是在第二次作业的基础上添加了双轿箱电梯。我完成任务的思路就是新创建一个新的类DCElevator,继承Elevator。新的类基于Elevator有多一个标识符A/B。算法上也做了一些调整,原本的电梯只有到达请求目标楼层或需要处理重置请求时才将乘客放出来,这次则多了个当向上乘客目的地>顶楼或向下乘客目的地<底楼也需要放出乘客的条件,并且和处理重置请求一样需要修改乘客当前所在位置。
另外,双轿电梯在进入换乘楼层前还需要判断其中是否有电梯,于是就需要添加判断换乘楼是否被占用,以及移出换乘楼的设置。
本单元作业的体会还是相当好的,我个人并不只当作作业来做。放在现实中,一个涉及多种类型部门的工厂/系统/公司都可能有类似的场景。即多种部门分别有自己可以处理的任务类型,在此就需要有一定的调度方案来确保问题能被高效的处理。相信经过第二单元的训练也让我在以后处理问题时,特别是需要同时间处理多项任务时,能够应对得更从容,有效。感谢课程组提供的这次机会。