OO-第二次总结

(1)同步块的设置和锁的选择,锁与同步块中处理语句直接的关系

  • 设置Elevator(电梯对象)和Input(读入方法)两个线程,同步运行。
  • 为了避免电梯在无需工作时轮询,将电梯的行为用synchronized封装起来,当满足“请求队列为空”、“电梯内无乘客”和“输入未停止”时,电梯用wait()停止,直到Input再次检测到输入数据,用notifyAll()唤醒电梯。
  • 第二、三次作业中加入了多部电梯(多线程),为了避免电梯之间冲突,对每一个对Queue(请求队列)的读写操作用读写锁封装。

(2)调度器设计,调度器与程序中的线程交互

  • 第一次作业:采用ALS策略,并没有设置单独的调度器模块,整合进了电梯行为中。
    ALS策略即:设置一个请求为主请求,电梯执行主请求,并在运行途中捎带副请求,当主请求完成后,从副请求和请求队列中再次选择一个主请求。以此类推。
  • 第二次作业:增加了多部电梯,单部电梯仍按ALS策略运行。
    因个人能力有限,没有想出合适的统筹规划方案。我采用的策略是让多部电梯“竞争运行”,没有使用单独的调度模块。
    所谓“竞争”就是例如当第一个请求进入队列时,不进行调度,所有电梯都设其为主请求,一起向该请求的起始楼层前进。由于使用了读写锁,最终请求只会进入一部电梯(此处具有一定随机性)。其余没有接到请求的电梯会重新设置主请求,以此类推。
    对于随机数据而言,没接到主请求的电梯看似做了许多“无用功”,实际上性能并不会变差。但由于策略具有随机性,可能出现极端情况。
  • 第三次作业:对电梯进行了分类,在第二次作业的基础上加入了一些贪心策略。
    因为C类电梯效率显著大于B类,B类又显著大于A类,因此我的策略是将请求分类
    1.“能被C类电梯接的长途移动”为C类
    2.“非C类而在奇数楼层进出”为B类
    3.其余为A类。
    C类请求由C类电梯接,B类请求由B类电梯接,A类请求由A类电梯接。不进行换乘操作。
    在Input模块里对请求进行分类,实际上是将Queue分成了A、B、C三部分,三类电梯分别对三个部分各自进行调度。同一类中的不同电梯仍采取第二次作业中的竞争制。

(3)架构设计与可扩展性

  • 第三次作业
  • 类复杂度
Class OCavg OCmax WMC
Elevator 4.44 7 40
Input 3.5 9 14
Mainclass 1 1 1
Queue 1 1 5
  • 方法复杂度
Method CogC ev(G) iv(G) v(G)
Elevator.Elevator(Queue,Object,int,ReentrantReadWriteLock,int) 3 1 1 4
Elevator.check(PersonRequest) 5 5 5 6
Elevator.getFirstRequest(Queue,int) 3 3 2 3
Elevator.judgeFlag(PersonRequest) 2 2 1 2
Elevator.leave() 14 1 6 7
Elevator.move(int) 14 1 4 6
Elevator.pick() 18 1 10 11
Elevator.run() 13 1 9 9
Elevator.setMainRequest() 4 1 3 3
Input.Input(Queue,Object,ReentrantReadWriteLock) 0 1 1 1
Input.judgeType(PersonRequest) 7 3 1 11
Input.run() 17 1 9 10
Input.setLock(Object) 0 1 1 1
Mainclass.main(String[]) 0 1 1 1
Queue.getQueue() 0 1 1 1
Queue.getStop() 0 1 1 1
Queue.getfirst(int) 0 1 1 1
Queue.setStop(boolean) 0 1 1 1
Queue.setfirst(int,int) 0 1 1 1
Elevator.pick()复杂度最高,负责处理开关门、请求进入电梯、请求队列的重新排列。
  • UML类图
  • UML时序图
  • 可拓展性
    • 没有设置单独的调度器,策略被整合在Input中,可拓展度较低。

(4)自己程序的bug

  • 第一次作业在强测和互测中没有被hack
  • 第二次作业在互测中没有被hack,在强测中RTLE了一个点,但在课下自己测试时却能通过,疑似是策略随机性的问题或是服务器与本地行为不同。
  • 第三次作业强测通过,互测中被hack了一个点。是全为A类请求的极端情况,我的策略无法通过。

(5)别人程序的bug

  • 本次作业并没有hack成功orz
  • 三次作业中分到的小组成员被hack的点均为RTLE,是策略不当的问题。

(6)心得体会

  • 反思
    • 本单元偷懒采用了电梯的竞争制,没有思考出合适的调度策略,导致极端情况过不了。
    • 对于Morning和Night情况没有做单独分析,全部使用了Random模式的策略。
    • 在写第二次作业时自己造了好久轮子,没有用现成的读写锁,浪费了大量时间。
  • 心得
    • 本单元比上次进步的地方在于,第一次作业加了把劲,实现了推荐的ALS策略,使得第二和第三次作业的迭代变得轻松很多。
    • 学习了java多线程和锁的使用,进一步理解了面向对象的思想。
  • 总结
    • 本单元比上单元轻松了许多,希望下个单元也能再接再厉。
posted @ 2021-04-25 17:23  NoMansLand  阅读(79)  评论(1编辑  收藏  举报