面向对象第二单元博客

第一次作业

 作业内容

 第一次作业的要求为仅有五部跨楼层的电梯。乘客的请求也仅仅是同一楼座。可以看出第一次的作业要求较为简单,主要是熟悉多线程的相关实现。

 实现方式

 线程

 在这次作业中,我采取了三组线程——输入线程,调度器线程,电梯线程。三者共享两组队列,该两组队列即为同步块。
 第一组队列为输入线程与调度器线程的队列,在得到输入后将数据写入该队列,等调度器读取。调度器读取到请求后,再更根据请求的种类,将其写到第二组队列中的一个。之后电梯读取到该请求,并作出相应的行动。

 锁

 关于锁方面,第一次作业时没有过多的考虑这方面,之后在迭代开发的过程中也没有进行修改,三次作用都使用了最简单的使用关键字synchronized的方式。可能也是使用不同锁在个人看来对测试的性能无影响。故之后的两次作业不在讨论锁的选择。

 调度器

 第一次作业的调度较为简单,即根据不同的楼座分配给对应的电梯即可。

 电梯策略

 采用了类似于als的算法,但是电梯的移动的目标不为主请求的目标,而是当前移动方向最远的目标。

 代码分析

第一次作业的协作图和uml类图分别如下。
image
image


第二次作业

 作业内容

 第二次作业,在第一次作业的基础上,添加了横向电梯,以及增加电梯的请求,乘客的请求也相应的变成了单次横向请求或者单次纵向请求。
 由于架构的选择,这次作业我更改的东西并不是很多。仅仅将原来的电梯替换为了电梯组,并为不同的电梯组配备了不同的移动逻辑。

 实现方式

 线程

 本次作业采用了流水架构,一共有五组线程。输入线程,调度线程,建造线程,电梯组线程和电梯线程。同步块即为各个线程之间的共享队列以及电梯组。
 输入线程在得到输入后,根据请求的不同将其分配给调度线程或者是建造线程。调度线程会根据请求乘客请求的具体种类分配到电梯组,而建造请求则会调用电梯组的同步方法建造电梯。当电梯组接受到请求后,也会调用自身类同步方法,将请求分配给一个电梯。
 在最初的时候也考虑过,不设计建造线程,无论是请求乘客请求还是建造请求均分配给对应的电梯组,让其自行处理请求。这样能提高模块之间的独立性。但是因为该做法会使调度线程变得较为复杂,故没有采取该方式。
 仔细思考了一下,好像这种做法确实比现有的设计要好。,降低线程数量的同时减少了互斥块的产生。

 调度器

 由于是流水架构,存在三个小调度器。第一个是调度乘客请求与建造请求进入不同线程,第二个是细化乘客请求进入不同电梯组,第三个则是电梯组内将请求调度给不同电梯。

 电梯策略

 总体上的请求的处理为预分配。组提前将请求分配给不同的电梯,让电梯自行完成任务的处理。具体组的选择则采用了顺序分配的方式。(本来预期采用的权重分配,由于电梯的信息并没有暴露,故放弃了该做法。)
 竖直方向的方法同一。
 水平方向的方法则采取的指导书中所写的方式。

 代码分析

第二次作业的协作图和uml类图分别如下。image
image
(第二次作业无右边的sequence相关类)


第三次作业

 作业内容

 第三次作业的在第二次作业上的基础上除去了乘客请求的限制,即楼层和楼座可以都不相同。并且对电梯进行了个性化定制,每个电梯的载客量、速度以及横向电梯的可达到性有输入信息决定。
 对于速度和载客量,只需更改电梯的相关属性即可;对于横向电梯的可达到性,在每次分配前进行判断;而乘客请求的拆分则是我这次作业的主要修改内容。

 实现方式

 线程

 本次作业采用了流水架构,一共有八组线程。出去第二次作业中的五组线程,多出来的三组均用来控制乘客请求的拆分(统称为拆分线程)。输入线程与拆分线程共享容器,而拆分线程在一个请求投入或者是一个请求的部分处理完之后,向等待队列写入合适的请求。相当于在作业二的输入线程和调度线程之间插入了新的过渡用的同步块。

 调度器

 这次作业多出来的额外的调度即为对横向电梯的调度。具体有两种情况:
  1.横向直接可达
  2.横向间接可达
 如果一个电梯能够直接到达所要求的两座之间,则该称电梯为横向直接可达,有该电梯所在的层为横向直接可达层;如果需要多次横向换乘,即A->B,B->C,且不直接可达电梯,则称该层为横向间接可达层。
 当然,除此之外,也可能存在需要多次横竖换乘的到达方式,但其过于复杂,此处不讨论。
 基于易于实现的目标,选择了一个横向直接可达的,且层数合适的层来作为中转层。

 电梯策略

 横竖电梯的运行策略都和第二次作业没有改变。

 代码分析

第三次作业的uml类图分别如下。
image

测试与BUG

 测试与互测

 对于自我的测试,主要还是聚焦于功能性方面和多线程方面。功能性方面为电梯是否能处理不同的单个请求。多线程方面则着重考虑同步块是否存在问题,以及线程是否能够正确的运行(不论询,不死锁,能够正确的开始与结束)。
 对于互测,则以观察同学代码的一些特征为主,即一些步骤的合理性。如果有发现问题,则基于问题来构造数据。

 BUG

 第一次作业

 强测与互测均无bug,互测中发现了部分同学输出时间戳不递增的问题。

 第二次作业

 强测与互测均无bug,互测未发现同学bug。

 第三次作业

 强测与无bug,但由于对同层请求做了特判而未解决,在互测中被多次hack,互测未发现同学bug。

反思与总结

 第二次作业的总体情况尚可,所构建的模型能够较好的处理问题,但仍然存在一些基础的逻辑欠缺。在多线程方面,则有了一定的了解,但对于一些方法,由于未能自己实现,故掌握程度较浅。

posted @ 2022-05-02 19:11  荀彧1732  阅读(22)  评论(1编辑  收藏  举报