OO第二单元总结

OO第二单元总结

同步块的设置和锁的选择

第一次

在第一次作业中,在我采用的设计中,共享对象只有RequestQueue一个类,所以在用到其时,直接使用synchronized锁以确保线程的安全。而对于同步块的设置,在第一次作业中,由于仿照实验的写法,在RequestQueue的方法上加上了synchronized,所以绝大多数直接使用了方法,而没对对象设置。

第二次

第二次作业相较于第一次作业,只增加了横向的电梯,而逻辑上的区别不大,因此同步块的设置和锁的选择和第一次一致

第三次

第三次作业,相较于前两次的作业,由于横向的电梯存在着可达性的判断,在选择具体的电梯时也需要楼层,速度等信息,所以我在MainclassSchdule这两个类之间利用多个HashMap来传递信息,而HashMap本身是线程不安全的,所以我用了一个类Eleinfo来放置多个HashMap,并而访问其中的信息时,均通过这个Eleinfo类来进行,而访问时的Synchronized锁就加在这个类上。

调度器设计

第一次

在第一次作业中,由于只有五台电梯,我的调度器直接从waitQueue中取出Request后,根据所在的楼座直接放入对应电梯的requestQueue即可。

第二次

在第二次的作业中,加入了横向的电梯以及一个楼座中多台电梯的情况。则在第一次的基础上加入了对PersonRequest横向和纵向的判断,以及通过比较同一楼座中每一个电梯中已经有的人数,选择加入到人数较少的电梯的requestQueue的队列中去即可。

第三次

在第三次的作业中,由于加入了中转,我将所有的PersonRequest分为了三步,并在调度器中对于步骤执行完的,认定为完成,第一、三步未执行的,认定为加入纵向电梯队列中,第二步未执行完的,认定为加入横向队列中。

同时,在第二次的基础上,将同一楼座、层数的电梯的选择,由根据人数改为根据人数和速度。

总体而言,调度器与其他线程的交互,主要是通过共享对象,在本作业中,即各个请求队列。

框架模式

架构设计和未来扩展能力

第一次作业的整体架构较为简单,在MainClass里创建Elevator的线程,接受读入的信息,在这里,我并没有建立Input这样一个类来处理输入的信息,直到第三次也没有,发现,尽管这样做是可行的,但是会导致MainClass中存在大量的代码,耦合性强,在我第二次、、第三次修改的时候,并不方便。在Mainclass接受到输入的Request后,放入到一个作为共享对象的队列中去,传给Schdule。即采用了生产者消费者的模式。在Schdule这个类中将Request分配给各个电梯。由电梯自己负责自己的运行。

而电梯的具体策略,做为一个类放在电梯中,这样可以在更改电梯的具体运行策略时较为方便

而在第二次作业中,加入了横向电梯Crosselevator这样一个类以及对应的策略,尽管在第一次中考虑到了电梯可能有不同的策略这件事,但是横向电梯的具体运行由于存在着环形的问题,和纵向电梯的运行差距较大,不是仅仅更改运行策略就可以实现的,所以重新写了横向电梯类。而其他的方面与第一次作业的架构类似。均是由Schdule分配请求给电梯。

在第三次的作业中,发现由于创建电梯所需的代码量较大,将创建电梯这一步骤放在原本的位置,使得代码量变大,难以发现问题,因此建立了一个类用于创建电梯。同时由于将一个PersonRequest分为三步执行,但是如果直接利用提供的类,无法记录执行到了哪一步,因此建立了Person类,在其中保存已经执行了的步骤。同时,建立了Eleinfo类,作为MainClassSchdule之间的共享对象传递信息。

同时,由于并不是人坐一次电梯就结束了,因而仿照实验写法,建立了RequestCounter类用于判断是否结束。

对于未来继续的可能的扩展,认为没有建立Input的类处理输入,是不利于扩展的。同时,强行认为每个人的路径分为三步,在未来的扩展中,也是非常不利的,对于可能的多次换乘,或者特殊的要求,均难以扩展。认为可以用一个属性,保存所需要的总的各个步骤,在Input中得到这些步骤,是相较于当前更适合扩展的方法。而对于电梯的可达性,电梯的策略,这些方面,则是较为容易进行扩展的。

UML类图

 

 

UML协作图(sequence diagram)

 

 

bug分析

  • for循环移除元素时,忘记将当前标记减1

    重写为用iterator

  • 发现在代码量较大的地方,容易出现输入的错误

    • 在判断选择横向电梯时,打错了比较的楼层,导致了添加的电梯全部没能使用,RTLE

      改回正确的楼层判断

    • 第三次作业选择中转楼层时,忘记让不用换乘的请求的中转楼层设置为fromfloor,从而出现到默认的1楼换乘的现象。

      加上一个判断,在不用中转时,transfloor等于fromfloor

发现别人bug的策略

通过对代码的观察,主要检查遍历是否有问题,是否存在线程不安全,手动构造一些样例。

但由于个人较为懒惰,大多数情况下看了一点就开摆了。

因为多线程的偶然性,bug难以复现,本单元的bug较难寻找。

心得体会

线程安全

在本单元的学习中,个人认为最大的收获就是对于多线程的学习,从对于多线程没有一点了解到了现在至少知道了基本的利用synchronized对于线程的安全性进行保证,保证对共享对象的操作互斥,并利用共享对象实现线程间的交互。

同时也了解了加锁中对象的选择,同步区的选择等等问题,并不是盲目的加锁就可以保证线程的安全,反而可能影响到实际的效率

同时,也知道了自己只了解了多线程的一小部分,对于更多的锁的类型,线程安全的类等等的了解还不够

层次化设计

感受到一个好的设计是可以带来很多的便利的,而在本单元中,采用了实验中给的生产者消费者模式,以及听取了研讨课中各个同学的分享,给我的架构起到了很多的帮助。也了解到了SRC、OCP等等设计原则,学习到了很多。

 

 

 

 

posted @ 2022-05-02 20:01  strly  阅读(27)  评论(1编辑  收藏  举报