BUAA_OO_2020_Unit2_Wandy

通过了这一单元,对于多线程有了些许理解,在此做个博客,既是完成作业,也是方便以后复习。

三次作业设计策略

三次协同和同步控制均采用 lockcondition 的模式,因为较为灵活,而且能约定时间,比较简单灵活,不易产生死锁。以下是简单介绍。

  • 第一次

    ​ 首次写多线程程序,以ddl为动力,以讨论区为资源,不断地探索与思考之后灵机一动,写了个带bug的小程序,采用sstf调度算法,仅主线程和一个电梯线程,两个线程交相进行,但尽管只有两个线程,还是出现了bug,惜得89。

  • 第二次

    ​ 看起来难度好像不大,依旧每个电梯单独为一个线程, 新增电梯调度器这个线程,依旧为sstf,调度器找最近的电梯来接人,为了锻炼自己的能力,沒有瞎锁,只在必要地方lock,基本没加什么锁,采用肉眼观察法验证了正确性后,交上去过了中测就没管了。但人看不如机测,互测被hack后,写了评测机,开测后果然自己是错误最多的,有时候判断不出来人满,强行连载十数人,令人叹为观止。自然强测炸了,错了四个数据点,惜得78。

  • 第三次

    ​ 前两次的失败,让我感觉该放下OS,好好OO了,由于需要换乘,在Person类中直接static了一个大策略,即从[-3, 20] -> [-3, 20]的策略都直接自动生成了,而且每个有多种策略,每个策略使用不同的电梯,每个策略都是这个或这两个电梯的最小时间策略,最多使用两种电梯。如下所例:

    18 -> 1: 18 -> 1 in A, 18 -> 15 in A 15 -> 1 in B, 18 -> 15 in A 15 -> 1 in C

    ​ 之后通过 public void setRequests(Boolean[] busys) 这个函数根据当前各类电梯的空闲程度对每个乘客选择合适的策略。之后每个电梯自行调度,public static long getTime(args) 得到上行或下行满足所有乘客需求所需要的时间,选择时间最少的方向,通过递归来实现。

    ​ 又写了个评测机,七种模式来随机,但还是没能测出我的bug,因为我的评测机是不管cpu实际运行时间的,但在互测被hack16次,有两处破绽:一个是由于电梯选择策略是static块的初始化,导致第一次用的时候才开始初始化,不在一个线程容易出事。还有一个是在一个人所有策略都行不通时,会标记而且把它放在队尾,让下一个人上,即 remove 后 offer,可惜,我用的是 PriorityBlockingQueue,会自动排序,导致一直轮询,cpu_run_time_limited,所幸强测机也没测出,幸得99。

第三次作业SOLID分析

Single Responsibility Principle

如上图所示,每个类的作用相当单一

Open-Closed Principle

由于使用了一个TypeElevator 这个枚举类,如果所有类型的电梯使用同一种方法,如果增加电梯功能仅需在Elevator加一个方法即可,如果增加电梯种类只需在TypeElevator中加入相关数据。

Liskov Substitution Principle

无继承,pass

Interface Segregation Principle

无接口,pass

Dependency Inversion Principle

???,pass

度量分析

TypeMetrics
Type Name NOF NOPF NOM NOPM LOC WMC NC DIT LCOM FANIN FANOUT
Elevator 12 2 19 8 316 56 0 0 0.315789474 0 0
ElevatorController 6 0 11 7 189 35 0 0 0.181818182 0 0
MainClass 3 2 2 2 33 6 0 0 0 0 0
Person 5 0 22 20 213 47 0 0 0.318181818 0 0
RequestOfPerson 4 0 10 9 53 13 0 0 0 0 0
SimpleRequest 3 0 6 6 25 6 0 0 0 0 0

嗯,虽然看不太懂,但是感觉不错。

MethodMetrics
Type Name Method Name LOC CC PC
Elevator compare 8 2 2
Elevator Elevator 12 1 3
Elevator run 39 6 0
Elevator finished 10 1 0
Elevator arrive 9 2 1
Elevator updateDes 28 10 0
Elevator getTime 64 11 5
Elevator goOutElevator 5 2 1
Elevator judge 8 2 3
Elevator goInOut 7 2 0
Elevator OpenDoor 16 1 1
Elevator goIn 16 2 1
Elevator goOut 35 4 1
Elevator goOutPerson 9 3 0
Elevator goInPerson 9 3 0
Elevator isFull 9 1 0
Elevator getlocation 3 1 0
Elevator addPerson 10 1 1
Elevator isFinished 3 1 0
ElevatorController ElevatorController 25 3 0
ElevatorController compare 3 1 2
ElevatorController run 36 5 0
ElevatorController elevatorFinished 10 4 0
ElevatorController pushToElevators 45 8 1
ElevatorController allHasWaiting 8 3 0
ElevatorController isFull 13 4 0
ElevatorController getLock 3 1 0
ElevatorController getCondition 3 1 0
ElevatorController addPerson 12 2 1
ElevatorController addElevator 26 3 1
MainClass main 25 5 1
MainClass isFinish 3 1 0
Person reverseRequests 7 2 1
Person printBase 15 5 0
Person hashFloor 3 1 2
Person fillList 6 2 4
Person getMethod 40 12 3
Person Person 6 1 1
Person breakDownRequest 3 1 0
Person regFloor 8 2 1
Person setRequests 20 4 1
Person arrive 4 1 0
Person getFromFloor 6 2 0
Person getToFloor 6 2 0
Person getType 3 1 0
Person getPersonId 3 1 0
Person recover 6 2 1
Person isWaiting 3 1 0
Person notWaiting 3 1 0
Person ifWaiting 3 1 0
Person isInElevator 3 1 0
Person goinElevator 3 1 0
Person gooutElevator 3 1 0
Person getDes 6 2 0
RequestOfPerson RequestOfPerson 6 1 2
RequestOfPerson RequestOfPerson 6 1 3
RequestOfPerson addRequest 3 1 3
RequestOfPerson clone 3 1 0
RequestOfPerson toString 7 2 0
RequestOfPerson reverse 7 2 0
RequestOfPerson getSimpleRequestNow 6 2 0
RequestOfPerson finishSimpleRequest 3 1 0
RequestOfPerson hasFinished 3 1 0
RequestOfPerson getState 3 1 0
SimpleRequest SimpleRequest 5 1 3
SimpleRequest getFromFloor 3 1 0
SimpleRequest getToFloor 3 1 0
SimpleRequest getType 3 1 0
SimpleRequest toString 3 1 0
SimpleRequest reverse 3 1 0

CC高的几个都是和优化算法有关。

类之间仅有相互调用的关系,类图没啥用。

BUG分析

已经在设计策略分析了。总之,用了 lock 和 condition,很难有死锁,但是还是要仔细考虑同步问题。

分析别人BUG

评测机并发测试一千例,subprocess模拟输入,wait(210),超过就是TLE,加上 check.py 自己写了几个类模拟电梯运输并且判断了时间,除了轮询测不出来真实cpu时间,其他很稳。数据生成有七个类型,针对不同楼层,不同电梯类型,以及不同的时间间距,但随机性还是太大,不太好,但还是测出来不少bug。

心得体会

对多线程运作更加了解了,有一个好的设计可以减少很多需要用锁的地方,不要暴力全加锁。

posted @ 2020-04-16 12:07  Wandy666  阅读(159)  评论(0编辑  收藏  举报