2024北航OO课程第二单元总结

北航OO课程 第二单元总结

写在前面

  • 这一单元是OO课程中难度最大的一个单元,有学长说一千个人就有一千种OO电梯,我深表赞同,由于多线程的复杂性和灵活性,同学们的架构千奇百怪,导致我们在互相讨论的时候也出现了各种不能兼容的思维问题,所以无论编写程序还是debug难度大大增加。
  • 不可否认的是,这一单元也是收获颇丰的一单元,随着迭代的进行,我对多线程的理解不断加深,而且也更能够将问题抽象化、模块化,有了一些自己的思路,在此简单介绍,以供各位批判

第五次作业

设计要求

  • 本次作业要求模拟一个多线程的实时电梯系统
  • 该系统具有上下行、开关门的功能,并可以模拟乘客的进出
  • 本次作业给定乘客搭乘电梯的编号,即乘客自行选择进入哪部电梯
  • 系统初始在1层有6部电梯,每部电梯的编号、速度、开关门时间和限乘人数都已给定

思路

  • 三个线程类InputScheduleElevator,分别负责输入、分配请求、电梯运行
  • 请求类Request、请求队列类RequestQueue,其中RequestQueue类充当共享变量,用来实现总请求队列和电梯的请求队列
  • 采用生产者-消费者模式,Input为生产者,Schedule为一级消费者和生产者,Elevator为二级消费者接受来自Schedule的请求
  • MainClass主线程中创建总请求队列、输入线程、调度线程以及电梯线程
  • 由于请求的电梯编号固定,因此只需要通过调度器将乘客放入该电梯的请求队列即可
  • 电梯中包含Strategy类,用于决策电梯的下一步动作和是否转向

UML类图
请添加图片描述

调度策略

  • 本次没有电梯调度策略,因为电梯编号固定

运行策略

  • 对于单电梯采用Look策略,该策略是Scan算法的优化,能够更合理的运行
    • 如果前方有请求或者电梯中请求未完成则按当前方向继续运行
    • 如果电梯为空且电梯运行方向前方没有请求且本层楼也没有同方向请求则转向
    • 只捎带同方向的请求
  • 借用往届学长的思路,可以采用量子电梯来缩短运行时间
    • 要求中规定运行时间为0.4s即关门到下一楼层的时间为0.4s,我们可以要求电梯在原地等候,0.4s后瞬移到下一层即可,这样代表还能处理这期间的请求
    • 另外开门使用0.2s,关门使用0.2s,只需要保证开关门之间间隔0.4s即可,所以我们可以记录上次相关操作的时间,执行完操作后只需要sleep(400 - (currentTime - lastTime)) 即可,若操作时间大于0.4s,则不睡觉直接关门后移动
  • 该运行策略一直沿用至Hw7,后面不再赘述

同步块

  • 特别提醒,同步控制的锁要加在方法上
  • 注意改变队列要notifyAll()
  • 要采用Get-And-Remove的方式,即查询后删除,不然可能会出现同时读写问题
  • 由于共享变量是RequestQueue,所以如果要遍历请求队列一定要在RequestQueue中,如果取出容器在外部遍历很有可能出现同时读写问题,外部遍历一定要加好同步控制!
  • 锁本身是访问权,拿到锁才有访问资格

出现的bug
由于没有理解好共享变量的概念,将共享变量中的容器取出后在电梯方法中遍历,出现了同时读写问题

public void whoToPickUP(Elevator elevator) {
		 ArrayList<Request> requests = requestQueue.getRequests();
         for (Request request : requests) {
           ...
         } 
}   //wrong

在此处设置同步控制即可

public void whoToPickUP(Elevator elevator) {
        synchronized (requestQueue) {
            ArrayList<Request> requests = requestQueue.getRequests();
            for (Request request : requests) {
              ...
            }
        }
}//right!

第六次作业

作业要求

  • 本次起不再指定乘客进入电梯号,可以自行设计调度策略
  • 新增Reset指令,接受该指令后电梯重置,修改容量和运行速度

思路

  • 整体架构沿用上一次作业
  • 新增Reset类,该类继承Request类,用于实现重置请求
  • 沿用上次请求处理思路,将重置请求放入请求队列内,若处理请求时检测到重置请求,则立马停止工作开始重置
  • 新增ShadowElevator类,用于模拟单电梯运行
  • 重写调度策略

UML类图

请添加图片描述调度策略

  • 采用影子电梯策略模拟电梯运行从而做出局部最优选择
  • 影子电梯采用深克隆来获得电梯当前的请求信息和运行状态,模拟该电梯加入当前请求后的运行时间从而将请求分配给最早能够完成当前所有请求的电梯
    • ShadowElevator类实际是ElevatorStrategy类的整合
    • 将运行方法改为一般方法
    • sleep(400)改为runtime += 0.4
  • 实际上并不完全准确,可能会出现模拟完后电梯状态发生改变从而决策失误的情况,但我们认为CPU运算速度要远远快于电梯状态改变的速度,因此在绝大多数情况下可以正确模拟

运行策略
沿用上次作业运行策略

同步控制
没有新增同步控制

出现的bug

  • 强测没有bug
  • 互测出现了bug,由于reset请求的出现,可能会有一个电梯率先完成重置其余电梯仍然在重置导致所有请求分配给了这个电梯,会出现运行时间过长的问题
    • 需要限制过多电梯重置时不进行请求分配,等待一小会

第七次作业

作业要求

  • 新增DcReset请求,将电梯重置为双轿厢电梯,规定A轿厢只能在换成楼层下区运行,B轿厢只能在换乘楼层上区运行,且不允许两个轿厢同时出现在换成楼层

思路

  • 整体架构依然沿用上次作业
  • 新增DcReset类继承Reset类,用于新的重置
  • 新增DcElevator类继承Elevator类,用于实现双轿厢电梯
  • 新增ShadowDcElevator类用于模拟DcElevator
  • 新增Output类,封装输出方法,适应不同类型电梯的输出
  • 新增ExFloor类,充当换乘楼层,作为共享变量存在,控制双轿厢不同时进入
  • 新增ExNumber类,全局计数功能,用于统计当前未完成请求数,用于判断是否可以结束运行
  • 重写调度策略

UML类图

请添加图片描述
调度策略

  • 采用影子电梯策略模拟电梯运行从而做出局部最优选择
  • 本次与上次略有不同,由于存在换乘策略,在模拟时只考虑全部请求均进入电梯即结束模拟,即请求队列为空则结束模拟
  • 另外由于双轿厢电梯耗电量低很多,所以在本次调度中加入对电量的模拟,用数组计算总电量,并按照一定比例将电量与速度进行线性拟合,从而找到比较合理的综合指标

运行策略
沿用上次作业运行策略

其他策略

  1. 判断是否结束运行
    采用了全局计数的方式,如果Input有新的乘客请求则++,若请求正式完成则--,最后判断是否全部完成且输入结束即可
  2. 防止双轿厢电梯相撞
    ExFloor类来实现互斥,在每次move之前判断是否下次进入换乘楼层,若进入则对换成楼层的状态进行判断,空闲则可以进入并修改状态为占用,离开时修改状态为空闲

出现bug
由于沿用了上次作业的架构,但是计算量翻倍,出现了CTLE的问题,具体修改方法为在电梯重置时调度器不应该轮询,而应该等待部分电梯重置完成后唤醒线程

心得体会

  • 在多线程的程序中,由于线程运行的不确定性,在处理相关bug时会出现不能复现的问题,甚至在修复时可能出现重复提交一次即可通过的情况,debug十分困难
  • 线程安全是程序设计时必须要考虑的一个因素,直接关系着程序的稳定性和性能,我们在编程时应该尽力避免线程之间的无意义互动和通信,同时在设计、编写、测试时都要反复考虑线程安全问题,这样才能避免各种无意义bug的产生
  • 电梯这一单元的层次化设计并不复杂,总体采用生产者-消费者模式,只是随着迭代的进行修改调度策略以及相关的运行策略即可
  • 不要过度考虑性能问题,更多的要从本次作业的实现中考虑结构上的、设计上的问题,拥有一个良好的架构才有可能创造出更好的性能
  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
《复变函数与积分变换》是北京航空航天大学出版的一本教材,主要介绍了复变函数和积分变换的基本理论和方法。复变函数是在复数域上定义的函数,它具有一些不同于实数域上函数的性质,如解析性、留数定理等。积分变换则是以积分为基础的一种数学变换方法,可以用于解决复杂的函数问题,如傅立叶变换、拉普拉斯变换等。 在这本教材中,作者详细介绍了复变函数的基本概念,包括复数、复变函数的连续性、解析性、留数定理等内容。同时还介绍了积分变换的基本理论和方法,包括积分的性质、傅立叶变换、拉普拉斯变换等内容。通过学习这本教材,可以帮助读者深入理解复变函数和积分变换的理论知识,掌握相关的分析方法和计算技巧。 此外,这本教材还包括大量的例题和习题,可以帮助读者巩固所学的知识,提高分析和解决问题的能力。同时还附有详细的解答和说明,可以帮助读者检查学习成果,及时纠正错误,提高学习效果。 总之,《复变函数与积分变换》是一本全面介绍复变函数和积分变换理论和方法的教材,适合北京航空航天大学相关专业的学生学习和参考。通过学习这本教材,读者可以系统地掌握复变函数和积分变换的理论知识,提高分析和解决问题的能力,为将来的学习和科研打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值