第二单元作业总结
OO第二单元的内容是电梯运行的模拟,三次作业由简到难,并且加入调度算法问题,很好地检验了我们的多线程编程的能力。
一、三次作业的设计策略、类图和优缺点
(1)第一次作业
第一次作业的电梯比较简单,不存在任何调度问题。我的设计就是开一个主线程和一个电梯线程,主线程负责输入请求,电梯线程接收请求并模拟运行。线程交互主要采取Queue类和wait、notify方法。

(2)第二次作业
第二次作业与第一次相比就是采用了ALS调度策略。本次作业我使用了三个线程,主线程输入请求,控制线程分析请求并转化为电梯的原子操作,电梯线程只负责执行控制操作。由于这个策略中电梯没有自主控制,电梯运行控制完全由控制器实现,并且我的原子操作设计存在很大问题,因此ALS策略未能实现,未能通过中测。
从类图中ElevatorAction可以看出,我的原子操作仅有向上运动1层,向下运动1层,进电梯和出电梯四种,因此当电梯首次服务时,代码是这样的:

而如果要实现捎带,就要在这么多个ElevatorAction中插入捎带人的所有操作步骤,是比较复杂的,到最后也未能完成。

(3)第三次作业
第三次作业不限调度,虽然限制四十条指令,但运行时间长达200秒,想要无损通过还是不难的。我这次改变了策略,首先将PersonRequest具体化成每一个人Person,拥有所在楼层这一状态信息,其次服务策略完全由电梯线程自己掌控,并去掉了控制器这个模块(虽然程序上存在,但并未起到实际的作用)。
电梯运行策略是这样的:每个电梯循环在最底层和最高层之间移动,每遇到一个合适的Person(能到达目的地,或能通过电梯自身转乘)就将其装入,等到达合适楼层时放出,而Person自身不存在任何主动操作。这一策略其实能够得到进一步优化,但我怕优化又会导致中测爆炸,并且四十条随机指令平均运行时间在100秒左右,足以通过测试了。

二、分析自己程序的bug
主要是第二次作业的bug。第二次作业挂在了中测,其实就是对于该捎带的请求未能处理好,根本原因就是设计不合理。现在来想,如果我要再次去做第二次作业,我会采用我第三次作业的策略,将控制放在电梯自身,并去掉原子操作这一设计,可能会更加简洁和方便。对互测bug,第二次作业没有能进入互测,其他两次在互测中没有被测出bug。
三、分析自己发现别人程序bug所采用的策略
对于电梯作业,我写了随机样例生成脚本和自动测试脚本,因此测试主要采取自动化测试,能否测出bug全靠运气。这是我在测试中做得不够好的地方。其实好的测试应该能够针对特定程序写出测试样例,而我只用了自动测试,这是不够的。在第一单元测试中,我反而主要用的是人工测试,因为那时还没有写出测试脚本。我认为,只有两种方法互用,才能更好地测试一个程序。
四、在本单元三次作业中获得的心得体会
这三次作业主要学习了多线程程序的组织和编写,以及线程安全的问题。对于读入请求的生产者-消费者模型问题,我采用的是队列加上wait、notify控制流程。除此之外,变量的线程安全在Java中体现为synchronized语句的使用。掌握了主要控制流程和安全结构,多线程程序写起来就会简单很多。
浙公网安备 33010602011771号