oo第二单元总结

综述

  这次作业的难度主要在于对多线程的学习理解和保证电梯的执行逻辑正确。这三次作业中,由于时间安排的问题,导致后两次作业在逻辑上没有实现完备性,出现了很大的漏洞。然后,在线程安全设计中,虽然没有犯错误,但是由于基本都是靠java原生的synchronized操作来实现的,所以,可能在效率上会有一些损失。一个还算好的有点是,这三次作业基本是按照一种模式写下来的,没有在架构上做太多的修正,基本都是根据每次作业的要求去重写类中的一些方法,而没有出现重写类和新建类的情况。

作业分析

第一次作业

  第一次作业相对较为简单,但由于刚刚接触多线程,所以在一开始写的时候,还是琢磨了一段时间synchronized如何使用。整体的架构基本是参考了生产者-消费者模式,把接收请求的Receiver当作生产者,Elevator当作消费者,RequestQueue当作一个托盘,采用单例模式,使其保持唯一性。在设计Elevator时,考虑了以后的拓展可能性,于是将电梯的功能分成了三部分,一个是获取并分派下一步的Elevator主类,一个是负责上下楼,开关门和输出相关信息的Lifter类,还有一个是负责管理上下人和电梯内人的ElevatorCar类,最后还构建了Person类,一个类似于PersonRequest的类,但只保存了id和toFloor信息。

  在执行时,Receiver负责传入获取的请求,Elevator每次运行时从RequestQueue中取走第一个请求,进行执行。当获取请求为空时,检查Receiver是否已停止,若停止则结束运行。

 

 

第二次作业

  第二次作业,基本是一样的架构。由于这次修改了调度策略,所以重写了Elevator的run方法,以及RequestQueue的getRequest,并添加了getSubRequest方法,用于获取捎带请求。它与getRequest的不同在于,如果获取为空的话,不会等待,而是返回,电梯继续执行。电梯每次先把第一个请求当作主请求,然后在接送主请求的过程中,每层获取一次捎带请求,同时判断是否进行上下人操作,上人是看电梯的请求执行队列中是否有人没上电梯且fromFloor在当前楼层,而下人则直接交给ElevatorCar去做。

  当获取请求为空,且Receiver关闭时,停止电梯。

 

 

 

第三次作业

  第三次作业是在第二次作业的基础上增加了两部电梯,和一些电梯的相关设定。总体的设计与第二次差不多,如果一个请求可以被一部电梯完成,就把它交给能完成的电梯中请求队列最短的那部。如果一个请求,需要多个电梯合作,就先计算出它的换乘最短方案,然后将方案和id初始化一个MultRequest,然后存入MultReuests里面,并把其第一步请求分配给合适的电梯。每当电梯执行完一个请求,就返回一个id队列,如果id队列里包含了MultRequests里的id,就将其执行步数加1,然后将下一步请求分配出去,直至MultRequest里的所有步骤执行完毕。电梯参数的设置,基本就是在lifter和car里面增加参数进行设置,并同时在相关方法中添加几条语句。

  当获取请求为空,且receiver关闭并且MultRequests为空时,电梯方可停止运行。

 

 

 

度量分析

 第一次作业

 

 

第二次作业

 

 

 

第三次作业

 

 

总结

  首先,前两次作业的run方法的复杂度都较高,这两次都是把整个电梯的执行策略全部写在了run方法里。第一次是因为没有把执行中可重复的过程抽象为方法,而第二次是由于时间安排的问题,导致写的时间太短,没有把执行的步骤抽象。第三次将其改写成方法,然后调用就减小了其的复杂度。然后,第三次做的main方法由于需要设置电梯的参数,就没有太注意复杂度。

Bug分析

   这三次作业中,第一次作业没有什么太大问题。第二、三次作业都出现了设计逻辑上的bug。第二次作业中,一是在接到主请求后,切换电梯运行方向时,出现了问题;二是,切换主请求后,忽略了主请求在之前作为捎带请求已进入电梯的问题。第三次作业中,则是由于沿路直接让捎带请求进电梯,而忽略了接主请求时电梯已满的情况。

  这些bug的出现,主要原因是由于作业时间没有安排好,第二次作业是在最后一个半小时才过的课下,没有留出时间debug。第三次则是,在截止前一个小时才发现了问题,但是由于多线程的不确定性,导致当时一直很难复现,故而第二天才发现了bug所在。

互测分析

   前两次互测,基本是没有参与的,第一次是由于比较简单,所以一直在尝试写一个课下评测,但是效果并不好。第二次,是由于交上去后,很快便发现了自己的bug,所以一直在de自己的bug。

  第三次互测,写了一个随机生成40条数据的小程序,然后一一对每个人测试,最后测出了几个bug。

心得体会

   首先,synchronized的锁机制知识非常重要,它保证了整个多项程的运行正确性和合理性;其次,通过最近学习的Lock类等java的多线程相关知识,也发现了简单地使用synchronized,可能也会造成性能方面的缺失。所以,在不影响正确性的情况下,以后可以尝试着使用其他锁方法来提高多线程的效率。

  其次,一个代码的执行逻辑是要保证完备性的,需要好好测试。后两次作业,都因为一些逻辑设计中的不完备,导致出现了很严重的bug。因为多线程的执行具有不确定性,所以一些bug很难在测试时被发现。所以,要在设计时,首先进行完备的思考,尽可能做到面面俱到,其次在每次增加条件时,都应考虑是否会造成新的可能性,避免顾头不顾尾。

 posted on 2019-04-24 18:03  Eric_Zhuo  阅读(302)  评论(0)    收藏  举报