第二单元是关于电梯的多线程作业,整个过程中需求不断拓展,在ZY大佬的尽心尽力帮助下,总算完成了作业,感激涕零!同样感谢FF大佬和助教姐姐的帮助!手动@以上。
第一次电梯作业
整体构思
- 傻瓜电梯调度算法(FCFS):电梯挨个执行请求,无优化算法
- 总共为三个线程
- 输入线程-调度器线程-电梯线程
- 使用arraylist进行线程间的交互
- 注意加锁同步
性能分析
- UML图
- 复杂度
Complexity metrics | |||
---|---|---|---|
Method | ev(G) | iv(G) | v(G) |
Dispatcher.Dispatcher(List,List) | 1 | 1 | 1 |
Dispatcher.requestEmpty() | 1 | 1 | 1 |
Dispatcher.run() | 5 | 5 | 7 |
Elevator.Elevator(List) | 1 | 1 | 1 |
Elevator.move(PersonRequest) | 1 | 5 | 5 |
Elevator.run() | 5 | 5 | 7 |
List.getSize() | 1 | 1 | 1 |
List.pop() | 1 | 2 | 2 |
List.push(PersonRequest) | 1 | 1 | 1 |
Main.main(String[]) | 1 | 1 | 1 |
Output.closeDoor(int) | 1 | 1 | 1 |
Output.openDoor(int) | 1 | 1 | 1 |
Output.peopleIn(PersonRequest) | 1 | 1 | 1 |
Output.peopleOut(PersonRequest) | 1 | 1 | 1 |
Request.Request(List) | 1 | 1 | 1 |
Request.inputEnd() | 1 | 1 | 1 |
Request.run() | 3 | 4 | 4 |
Class | OCavg | WMC | |
Dispatcher | 2.67 | 8 | |
Elevator | 2.67 | 8 | |
List | 1.33 | 4 | |
Main | 1 | 1 | |
Output | 1 | 4 | |
Request | 1.67 | 5 | |
Package | v(G)avg | v(G)tot | |
2.18 | 37 |
bug分析
- 此次作业较为简单没有发现特殊的bug
第二次电梯作业
- 整体构思
- 主要实现电梯内的LOOK算法,其余架构与第一次类似
- 引入了结束线程,在相应的位置唤醒结束线程对当前状态进行判断
- 另外使用了floorFlag记录应该到达的楼层位置,来扫描决定电梯运行方向
- 使用了信号量来进行同步控制
- 性能分析
UML图
复杂度
Complexity metrics Method ev(G) iv(G) v(G) Elevator.Elevator(ArrayList,int[]) 1 1 1 Elevator.checkState() 6 1 7 Elevator.comeIn() 1 5 5 Elevator.comeOut() 1 4 4 Elevator.listWait() 3 6 6 Elevator.move() 1 1 6 Elevator.run() 1 4 4 Elevator.threadSleep() 1 2 2 End.End() 1 1 1 End.GetEleEnd() 1 1 1 End.GetInputEnd() 1 1 1 End.SetEleEnd(boolean) 1 1 1 End.SetInputEnd() 1 1 1 End.run() 1 4 5 Main.main(String[]) 1 1 1 Output.arriveFloor(int) 1 1 1 Output.closeDoor(int) 1 1 1 Output.openDoor(int) 1 1 1 Output.peopleIn(PersonRequest) 1 1 1 Output.peopleOut(PersonRequest) 1 1 1 Request.GetEndKey() 1 1 1 Request.Request(ArrayList,int[]) 1 1 1 Request.inputEnd() 1 1 1 Request.run() 3 5 5 Class OCavg WMC Elevator 3.75 30 End 1.33 8 Main 1 1 Output 1 5 Request 1.75 7 Package v(G)avg v(G)tot 2.46 59 - bug分析
- 此次作业LOOK算法&结束进程的使用使得程序性能还不错,没有被找到bug,同样的也没有什么好数据找到别人的bug
第三次电梯作业
整体构思
- 对整个过程进行具体化的模拟
- 在这类与现实生活相关的问题中,将具体过程具体化趣味化的设计对降低暴躁度很有帮助
- 调度器对每个请求进行一定的判断后分发给相应的电梯
- 电梯能够到达请求起始楼层
- 电梯值得接该请求(最少能送一程)
- 迷惑3楼特判
- 电梯执行本电梯的请求队列
- LOOK算法
- 将需要换乘的请求生成新请求加入需要调度器分配的队列
- 结束进程
- 输入结束唤醒结束进程去检查调度器是否结束工作
- 调度器检查电梯运行状态,所有电梯运行结束才触发调度器结束
- 调度器结束同样唤醒结束进程去检查输入进程是否结束
- 当输入进程结束且调度器结束,则整个程序结束
- 性能分析
- UML图
- 复杂度
Complexity metrics Method ev(G) iv(G) v(G) input.Input.Input(Object,ArrayList) 1 1 1 input.Input.getEndKey() 1 1 1 input.Input.run() 3 6 6 mainlogic.Dispatcher.Dispatcher(Object,ArrayList) 1 1 1 mainlogic.Dispatcher.checkEnd() 3 3 4 mainlogic.Dispatcher.cutLine(PersonRequest) 1 1 1 mainlogic.Dispatcher.deliverRequest() 1 6 6 mainlogic.Dispatcher.eleEndReturn() 1 1 1 mainlogic.Dispatcher.initialElevators() 1 1 14 mainlogic.Dispatcher.miseryThird(PersonRequest) 4 5 6 mainlogic.Dispatcher.reachable(Elevator,PersonRequest) 2 1 2 mainlogic.Dispatcher.requestEmpty() 1 1 1 mainlogic.Dispatcher.run() 1 5 5 mainlogic.Dispatcher.worthy(Elevator,PersonRequest) 2 2 7 mainlogic.Main.main(String[]) 1 1 1 objects.Elevator.Elevator(String,ArrayList,int[],int,int) 1 1 1 objects.Elevator.actualRun() 1 1 6 objects.Elevator.checkEleEnd() 2 4 4 objects.Elevator.checkState() 6 1 7 objects.Elevator.checkTrans() 1 11 11 objects.Elevator.comeIn() 1 5 5 objects.Elevator.comeOut() 1 3 3 objects.Elevator.endExecute() 1 2 2 objects.Elevator.getContainer() 1 1 1 objects.Elevator.getLegalFloor() 1 1 1 objects.Elevator.getName() 1 1 1 objects.Elevator.getRequestList() 1 1 1 objects.Elevator.isEleEnd() 1 1 1 objects.Elevator.move() 2 5 8 objects.Elevator.nextLegalFloor() 7 1 9 objects.Elevator.notFull() 1 1 1 objects.Elevator.openDoor() 1 2 2 objects.Elevator.pushRequest(PersonRequest) 1 1 1 objects.Elevator.run() 1 4 4 objects.Elevator.setEleEnd(boolean) 1 1 1 objects.Elevator.threadSleep(int) 1 2 2 objects.Elevator.trans(int) 2 1 2 output.End.End(Object) 1 1 1 output.End.getDispatcherEnd() 1 1 1 output.End.getInputEnd() 1 1 1 output.End.run() 1 4 5 output.End.setDispatcherEnd() 1 1 1 output.End.setInputEnd() 1 1 1 output.Output.arriveFloor(int,String) 1 1 1 output.Output.closeDoor(int,String) 1 1 1 output.Output.openDoor(int,String) 1 1 1 output.Output.peopleIn(PersonRequest,String) 1 1 1 output.Output.peopleOut(PersonRequest,String) 1 1 1 output.Output.peopleOut(PersonRequest,int,String) 1 1 1 Class OCavg WMC input.Input 2.33 7 mainlogic.Dispatcher 3.09 34 mainlogic.Main 1 1 objects.Elevator 2.64 58 output.End 1.33 8 output.Output 1 6 Package v(G)avg v(G)tot input 2.67 8 mainlogic 4.08 49 objects 3.36 74 output 1.33 16 - bug分析
- 个人和同组同学的bug都集中在调度问题的考虑不周
- 分配请求考虑不周,对于3楼的特判没有完整写出,会造成请求不能上正确的C电梯,在AB电梯间死循环
- 换乘判断并未考虑完全,导致请求并未正确上下电梯,无法结束程序
- 教训:对特判问题要考虑全面,缺失一种情况就能导致程序的崩盘
总结
这个单元的作业还是收获颇丰的,虽然最后一次是分最低的一次(捂脸),但是关于架构设计以及实现过程都感觉比上一次更好(虽然还是有很多问题)。所以我认为对我来说这单元作业的价值已经体现了。
最后总结经验为
- 要先抽象具体问题,设计架构
- 实现时,可以具体化抽象问题让过程具有一些趣味性
- 多花时间在设计、思考上,而非实现
- 多与同学交流,个人思维很容易陷入定式
- 有一个思维清晰的大佬朋友,debug百发百中
- 心态要佳,要学习不坚持到最后一刻不放弃的精神(@zy)