OO第二次博客作业
Posted aaa711218
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OO第二次博客作业相关的知识,希望对你有一定的参考价值。
作业总结
第五次作业:多线程电梯
本次作业的设计思路是:共有5个并行的线程,分别是输入控制器(inHandler)、调度器(Scheduler)以及 a、b、c 三部电梯(Elevator)。程序开始后分别启动三部电梯以及输入控制器、调度器等五个线程。输入控制器的作用是判别输入是否符合基本语法以及是否结束输入,如输入合法则将输入的指令转化为标准形式传给请求队列类进行下一步判断;请求队列类在得到一个待判断的指令后会进行进一步判断,并且由于是模仿真实时间所以可以在这里判断出同质指令并剔除,若指令合法则加入到请求队列数组中等待分配执行。调度器则是以一个固定的频率不断扫描请求队列,每当发现有新的未分配指令就会进行分配并交给相应的电梯去执行。电梯则是以一种自动机的思路根据当前状态和当前指令运动并输出相应的信息直到输入已经结束且请求队列中没有未完成的指令。
整体设计我认为还是合理的,但是还是有一些更加细节的问题。其中有关线程安全的问题就是每一部电梯输出时的线程争夺,为此我将输出写成一个方法并使用 synchronized 进行加锁限制,保证了输出的顺序性。其次就是电梯误差时间的积累,由于程序运行本身需要时间,若是在模拟电梯爬楼过程中直接进行诸如 sleep(200) 这样的操作的话会导致误差不断积累变大,在指令数量增多的情况下会影响输出。为此我采用了“假时间”,也就是在电梯内部自设一个专属于电梯的时间,在每一次需要 sleep 和加载指令的时候进行同步和微调,这样就可以避免输出时的时间误差。
本次作业的 bug 是一个格式错误问题,所有的 INVALID 指令输出时都没有按照原指令的格式输出,导致被揪了 1 个 bug,在基本功能实现方面还是比较满意的。经测试未发现别人的 bug。
第六次作业:IFTTT
本次作业的线程设计是为每一个监视任务创造一个监视线程,并利用文件树快照来进行对比。首先先启动输入处理,读取全部的输入并将符合规格的任务加入到监控任务队列中。输入结束后按照输入的指令依次启动监视线程,若为文件则直接追踪文件,若为目录则递归获取文件树,每一次通过与上一次的快照对比来判断是否触发条件。由于 Java 自带的文件(File)类是线程不安全的,所以改写文件类为安全文件(safeFile)类来解决问题。在输出方面和多线程电梯一样通过synchronized 来加锁以保持输出顺序。
从类规模来看,safeFile类规模较大且重写方法较多,整体显得比较冗余,且 TestThread 中没有考虑到线程安全问题,容易造成隐患。Monitor 中的 run 方法嵌套也很繁琐,在真正的执行中会显著地降低程序效率。总体来说这一次的代码结构不是那么的尽如人意。
本次被发现的 bug 主要集中在只有一条指令的时候,原因是由于文件监控器启动时间太早导致第一条指令有些时候会直接错过,后来已修复了这个bug。本次未发现别人的bug。
第七次作业:出租车(1)
这次作业的思路有点类似多线程电梯,首先读入地图并判断合法性,然后开始创建100个出租车线程,每辆车初始地点随机确定,并且直接进入等待服务状态。之后开始读入指令,每一条指令读入后先判断合法性,若合法则加入请求队列。调度器用于不断扫描请求队列,每次扫描到新的请求就开始分配请求。每一个请求都会有一个抢单窗口期,在窗口期内进入抢单范围的每一辆出租车都会被加入到该请求的抢单出租车队列中,等到窗口期结束后选择最合适的出租车并派单,出租车改变状态去接乘客并输出相应信息直至订单完成。
在设计过程中我认为整体结构比较合理,但还是有细枝末节的问题,比如线程安全方面仍需锁住输出方法已确保顺序,时间误差方面仍使用假时间磨消误差。特别的,我修改了 pointbfs 函数,在程序读取地图的时候就让其计算全图每两点间距离并存入 D[ ][ ] 数组,这样就可以确保出租车运动时遵守严格的200ms,对于数据规模较大时的处理很有帮助。
本次程序在功能方面未被查出bug,但是在设计原则上违背了Single Responsibility Principle,原因是 run() 方法完全可以拆分出 addRequest() 方法来专门进行输入的处理和添加请求,但实际并没有这样操作,导致无法编辑脚本进行测试。在测试别人的程序时,我发现他的程序输出很明显体现出在接到乘客时没有休息1s,且在出租车运行过程中并没有完全遵从 200ms 一格的规则(然而 readme 有写所以不算bug了),数据规模大时还会迟迟不派单(300条指令)等 3 个 bug。
心得体会
在这个月的三次作业中,多线程的线程安全思想开始显得尤为重要,多线程编程时的困难性以及很多 bug 的不可复现性也着实增大了编程的难度。但是有挑战就会有收获,复杂的多线程提高了我对于 bug 的精准定位能力,也培养了我的耐性,希望可以在之后的作业中掌握更多的知识与技巧。
以上是关于OO第二次博客作业的主要内容,如果未能解决你的问题,请参考以下文章