BUAA_OO_Unit2总结

BUAA_OO_Unit2总结

一、整体概述

第二单元主题为实现多线程的实时电梯模拟,研究探索多线程协作、线程安全、设计模式等问题。

电梯单元的主要难点在于,在保证线程安全的前提下,设计出易于扩展的架构,同时保证性能。对此,我采用了单级托盘集中式调度的架构。三次作业迭代增量开发的过程中,我在电梯之间的宏观调度上主要采用自由竞争的策略,在单个电梯微观调度上则探索了不同的算法。实验和测试结果表明,这种设计有相对较好可拓展性和性能。

二、设计思路

类图

img

分析

第一次作业

第一次作业只写了两个线程:电梯进程和输入进程,并没有把调度器单独作为一个进程。只是一个很简单的生产者—消费者模式。

所以这次只是把”盘子“锁起来了,也就是下面代码中的scheduler,虽然名字叫调度器但是事实上它只是个“盘子”,并且我把它设置成了线程安全类,除了scheduler类和电梯的run()方法中用到了synchronized锁,其他地方都没有用到。

第二次作业

第二次作业考虑到实现的复杂度和以后面对第三次作业的可拓展性,参照实验课上的代码进行了重构,把调度器改成了进程,所以第二次作业共有三个线程:输入、电梯、调度器

这次用到锁的地方就比较多了,因为共享对象增多了,我们一个线程一个线程来分析

输入线程

  • waitQueue(总等待队列,与调度器共享的对象),锁住等待队列避免多个线程对等待队列中乘客的改变导致不可知的错误,锁住等待队列后向其中加入乘客请求

  • elevators(电梯队列,与调度器共享的对象),锁住电梯队列避免调度器在进行乘客分配时突然加入新电梯而导致分配出错,锁住电梯队列后向其中加入新增电梯

调度器线程

  • waitQueue(总等待队列,与输入线程共享的对象),锁住等待队列避免多个线程对等待队列中乘客的改变导致不可知的错误,锁住等待队列后将队列进行调度分配到各个电梯中,同时调用waitQueue的方法判断调度器线程是否结束

  • elevators(电梯队列,与输入线程共享的对象),锁住电梯队列避免调度器在进行乘客分配时突然加入新电梯而导致分配出错,锁住电梯队列从而计算电梯中乘客的平均数从而分配乘客

  • eachElevator.getMissions(每个电梯的等待队列,与电梯线程共享的对象),锁住电梯的等待队列避免电梯和调度器同时对等待队列的乘客进行操作导致错误,锁住等待队列后向其中分配乘客,同时调用相关方法进行乘客的调度

电梯线程

  • waitQueue(电梯自己的等待队列,与调度器共享的对象),锁住电梯的等待队列避免电梯和调度器同时对等待队列的乘客进行操作导致错误,通过等待队列判断目前电梯的运行状态并且进行乘客的“接待”,同时调用相关的方法判断电梯线程是否结束

第三次作业

未完成

三、度量分析

img

PS:未经过评测机测试。

四、Bug分析

因未提交有效作业,暂无bug分析。

五、互测分析

因未参加互测部分,暂无互测分析。

六、心得体会

  • 线程安全

  通过这单元的练习,我明白了线程安全是个很重要的问题,而对于同享数据的处理是重中之重。基本方法是在访问同享对象时加锁,但也不能一概而论,要防止死锁的出现。

  • 层次化设计

  通过这一单元的学习,我明白了要将有着不同功能的部分分成不同的类,并且类之间的耦合性要尽量低,尽量用一次传递来连接两个类。并且要提取类与类的相似之处,巧用继承和接口来层次化类,从而使得程序更加的层次化和高扩展性。

开学的第二个月由于疫情被迫网课,以及家中的一些事情打乱了自己学习生活的节奏,没能以很好的状态面对自己的学习生活,导致未能及时参与到学习测试中。在接下来的学习中我会加紧学习脚步,跟上同学们的学习步伐,在此也感谢老师和助教们的关心和帮助。

posted @ 2022-05-04 16:00  走马行川  阅读(31)  评论(0编辑  收藏  举报