• 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。

    心得体会

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

  • 相关阅读:
    LIKE谓词
    [C#网络编程系列]专题一:网络协议简介
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(三)
    zz让你成功的九个心理定律
    zz给 VSTO 插件、文档传送参数
    重构笔记
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(二)
    zzVSTO 先瘦身再发布:客户端配置文件
    zz将 VSTO 插件部署给所有用户
    (zz)Sql Server 2005中的架构(Schema)、用户(User)、角色(Role)和登录(Login)(一)
  • 原文地址:https://www.cnblogs.com/Wandy666/p/12711846.html
Copyright © 2020-2023  润新知