Part1 第一次作业
作业要求:
在共十一层的新主楼中,模拟实现可在所有楼层间运行的六台电梯组成的多线程实时电梯系统
架构和调度策略:
设置调度器,具体指requestTable类,在收到请求时,根据电梯的当前任务量,电梯内人数和电梯与目标层之间的层差,分别赋不同的权重,并且进行归一化后,将新请求分配给得分最低的电梯。
并且实现捎带策略,如果经过该层时,乘客方向和电梯方向一致并且电梯内人数还没达到容量上限,就捎带乘客。
具体类图如下
并且使用生产者消费者模式,可以帮助笔者更好的理清多线程的关系,具体而言
consumer角色是elevator类
producer角色是request类
channel角色是requestTable类
data角色是person类
关于生产者消费者模式的简单描述见下图
uml协作图如下
未来拓展能力:
只需要根据要求进行调度策略的调整即可,可拓展性较强
Part2 第二次作业
作业要求:
在第一次作业的基础上,动态Add电梯(添加新电梯),动态Maintain电梯(电梯需要修理,并且将电梯内乘客在两层内放出)
调度策略:
依然通过加权计算电梯得分分配任务,区别在于新增电梯的容量和速度与初始电梯可能不相同,因此在requestTable类中考虑电梯容量和电梯速度,将这两个因素也加权计入总分的计算。
针对新要求的拓展:
Add比较简单,只需要new出新的elevator对象并且调用start()方法启动线程即可
Maintain需要将电梯内乘客和电梯的请求都放出,而不仅仅只是放出电梯乘客,并且需要把电梯对应的请求表对象删除,否则可能会继续给已经Maintain的电梯分配新请求,这不符合题目要求。具体表现在对Elevator extends Thread类中run方法的修改
类图如下
uml协作图如下
主要增加request对requestTable中Maintain请求和add请求的传输
未来拓展能力:
当时猜测maintain的电梯被修复,只需要讲这种情况归为add即可,可拓展性比较不错
Part3 第三次作业
作业要求:
新增的电梯只能到达部分楼层,乘客需要换乘0次、1次...n次到达目的地,设计换乘方法送达乘客
针对新要求的拓展:
创建新的类Graph,以邻接矩阵的形式存储信息,共11个节点,以多边图的形式连接。
实现分为两步,第一步规划路线。第二步,每一段路线根据前两次的调度策略分配给不同的电梯。即:在多边图中查找路径后,选择两个节点中具体走哪一条边,而第一步选择路径只需要保证两个节点之间有边相连即可,第二步再选择具体的边。
具体而言,查找最短路径时通过使用dfs算法,选择出换乘次数最少、路径最短的线路,并且在每段线路完成后,如果乘客并没有到达最终楼层,而仅仅只是到达换乘层,则重新规划线路,因为很可能原计划的电梯被Maintain,导致计划需要调整,但实现并不困难,因为重新规划无非就是再次调用Graph中的方法,所以该方法可以被多次复用。
并且在Person类增加成员变量tempFrom,tempTo记录部分路程,如原本请求是1层到6层
,通过Graph中方法规划出线路1层到3层,3层到5层,5层到6层,通过第一段路程时tempFrom是1,tempTo是3,以此类推
类图如下
uml协作图如下
Part 4 综合分析
同步块的设置和锁的选择
性能要求较低,未采用读写锁等更高效的方法,而是粗暴地采取 synchronized 关键字修饰所有共享资源,但是本单元只读操作比较少,大部分需要读写,同时在部分方法中无法提前获知是否进行写操作(如获取 请求时需要读取所有出发地与目的地才能确定是否有可达性满足的请求,才能进行取出的写操作),所以synchoronized修饰并不会造成大量资源的浪费
易变性分析:
第二次作业仅仅增加了不同的请求类型,在request类和elevator类简单修改即可
第三次作业主要难点在于设计路径算法,和之前的架构没什么关系,我倾向于认为这是面向过程的算法设计,所以架构整体上没什么改变
综合而言,可拓展性比较好
bug和debug方法:
我根据电梯内最近的乘客和电梯外请求最近的乘客和电梯的方位判断是否需要转向,这会导致电梯内人满了,但是电梯外有个乘客很近,电梯到达目标层之后却因为满员而不能接入乘客,导致电梯不断徘徊。
增强循环无法在Arraylist变化后保持itrrator计数正确,循环出现commodation
和nullpointer等错误,修改为普通循环即可。
debug主要使用两种办法,第一使用idea编译器中的debug方法,观察线程的状态,可以看到电梯是否提前terminated或者一直在wait。第二种办法是使用大佬的评测机,需要具备基础的python知识,会配python3环境,配置系统变量,并且学会cmd运行python程序启动评测机。这个过程,也有萌新友好的网页版评测机,只需要把答案复制粘贴上去即可检验正确性
心得体会:
我其实挺喜欢多线程这个思想的,加上电梯其实和生活息息相关,我能强烈的感受到现在学习到的知识是有机会真正的投入实际生产改造一些事物的,所以我还算比较有热情。比起第一单元抽象的运算符,显然具体的电梯更加吸引我。
和同学们交流真的很重要,一个好的设计可以少走不少弯路。
使用成熟的设计模式也是值得推崇的,如生产着消费者模式,这是前人多次试错总结出来的适合开发的设计模式。
其实我不怕难,我怕指导不详细,评测机配环境的时候让我头疼了一阵,因为我是真的没学过python,不过好在现在学会了,接下来继续加油吧