BUAA OO 第二单元总结

BUAA OO 第二单元总结

同步块与锁分析

第五次作业中,我设计了一个线程安全的类OrderQueue,在这个类中,存在请求队列与候乘表,数据相关的类,通过分别加锁保证了请求队列和候乘表的线程安全与并行性能。而因为这个封装好的类,在外部不需要考虑线程安全问题,只需要使用OrderQueue就行,保证了整个程序的线程安全与简洁。

第六次作业中,OrderQueue加入了返回队列中请求数的功能,与请求队列加同一把锁。

第七次作业中,OrderQueue加入了获取对应电梯各个参数的功能,这是常量,不需要加锁。

调度器分析

调度器分为总调度器和电梯策略,电梯策略是每个电梯内部包含的,而总调度器与每个电梯对应的的OrderQueue交互。

在第五次作业中,总调度器采取直接分配到对应电梯的方法,而电梯策略采用LOOK算法。

在第六次作业中,总调度器采取通过比较可达电梯对应的OrderQueue中指令数量,将指令分配给当前指令数量最少的电梯的策略。而对于电梯策略,纵向电梯采取LOOK算法,横向电梯采取循环扫描的策略。

在第七次作业中,总调度器中通过DFS与代价函数找到耗时最短的路径,并通过divide方法分解指令,基于电梯ID号将指令分配到对应的电梯上去。电梯策略上与第六次作业大致相同,横向电梯策略加入了判断是否可以开门的功能。

架构设计与扩展能力

因为方法名多且复杂,为了把重点放在架构分析上,本次作业的UML类图只留下了类和类之间的关系。

第五次作业:

在经过详细的考虑后,我没有把调度器作为一个线程,因为我们可以发现SchedulerInputHandler之间不存在速度差,所以调度器不应该单独为一个线程。所以本次代码共有主线程,输入处理线程和电梯线程三种线程。

在调度上,我使用总调度器来将指令分配给电梯,而分配的方法将由分配策略SdlStrategy控制,同样的,电梯本身的运行也由电梯策略EleStrategy控制,这样实现了策略与实体的解耦。同时,两种策略抽象类都采用了工厂模式,为之后多种策略的拓展打好了基础。

在线程安全上,OrderQueue是自行设计好的线程安全类,即生产者-消费者模型中的传送带,线程之间的数据交互都会通过传送带进行,通过这样的设计,使得代码其他部分的线程安全不需要考虑,保证了程序结构的简洁。而官方输出包本身线程不安全,所以通过封装将其封装为SafeOutput类,实现了输出的线程安全。

第六次作业:

第六次作业相对于第五次作业架构上没有太大的变化。横向电梯的实现对我的架构来说非常的简单,因为实现了电梯与策略的解耦,我只需要单独写一个横向电梯的运行策略Circle,并将其加入电梯策略的工厂即可。这体现了我的架构的良好可拓展性和低耦合度。

又因为同一层可能有多个横向电梯,所以我的调度器策略采用了Balance策略,将请求分配给可达电梯中队列指令数量最少的电梯,实现了效率的优化。

第七次作业:

第七次作业需要实现换乘功能,这次作业电梯的运行策略只需要在横向电梯策略Circle中加入判断是否可以开门即可,而主要的工作是如何在总调度器中实现分解指令的功能。

本次作业总调度器通过DFS与代价函数找到耗时最短的路径,并通过divide方法分解指令并储存在Scheduler的哈希表里,通过AccordId策略基于电梯ID号将指令分配到对应的电梯上去。当电梯出人时,使用Update方法,从HashMap中根据ID查找指令,如果查到,就通过AccordId策略将指令分配到对应的队列中,以此实现换乘。

线程之间的协作关系通过UML协作图(sequence diagram)来展示:

bug分析

本单元三次作业在强测与互测中均无BUG被找到,

体现了一个合理的架构对代码的质量起到了决定性作用。

hack策略分析

通过自动化评测与构造特殊数据相结合的方式进行Hack,实践证明Hack策略非常有效。

通过构造几组容易导致线程安全的数据来发现线程安全问题。比如所有指令只涉及同一座的电梯,多个运行的电梯同时输出等。

本单元的测试策略主要是发现线程不安全的代码并将bug复现出来,而第一单元的测试策略是覆盖性测试所有表达式结构,也不需要考虑bug复现的问题。

心得体会

线程安全心得:

高并发的设计需要让每个不相关的任务独立,彼此独立地执行自己的任务。而相关的地方最好通过设计线程安全类解决,这样可以保证各个线程的行为是安全的,同时可以保证代码的简洁性。

层次化设计

使用了JAVA 设计结构中的 生产者-消费者模式,利用抽象层次与工厂模式提高了代码的可拓展性,实现了代码复用。同时通过合理的抽象层次降低了代码的耦合度,提高了代码质量。

在设计过程中,我遵循了设计原则SRPOCP

SRP: 类与方法的职责单一,不要承担过多的职责。

OCP:修改时不得修改原有代码,只能通过新增代码实现以修改目的。

posted @ 2022-05-03 18:47  MrSisyphus  阅读(11)  评论(0编辑  收藏  举报