OO第二次博客作业

一、设计策略及其变化

由于这几次的作业应用的线程的概念,在设计上需要不光考虑到功能性的实现,更要考虑到在多线程情况下,需要哪些线程(用户需求),共享什么内容(竞争资源),以及如果进行多对象的同时处理(调度安排),这样就需要考虑到多个对象同时需求同一对象时的分配问题。一开始的作业中我使用了大量的对象锁,但是在使用过程中发现了范围难以把握,常常写成死锁等问题,在后面的作业中利用了更多的方法锁,将已有的方法比如ArrayList的相关方法进行封装以构造线程安全的动态数组,这是从SafeFile得到的灵感。在最后一次OO实验还学习到了BlockingQueue,感觉在以后的作业中可以加以实现。

 

二、第五次作业分析:多线程电梯

度量:

度量上可以发现在调度策略中有过高的圈复杂度。基本都是写了for循环的嵌套,并且在其中掺杂了很多if判断,导致整个Scheduler线程比较复杂,也能看出Scheduler这个线程的方法过多,需要精简和分散,防止出现一个类中方法过多过于全能,写成了面向过程的程序。

 

类图:

类图方面,Scheduler通过继承前次作业的调度器,并且重写了相关方法。Elevator实现了ElevatorCarrier的接口,在主方法里通过构造请求队列RequestQueue对象,三个Elevator线程,一个InputHandler线程,一个Scheduler线程来进行多线程的电梯调度。

 

UML协作图:

 

问题及不足:

这次作业的问题主要是对于synchronized使用不当,导致出现了大量不必要的等待,并且锁的范围把控不好,导致死锁忙等问题。在设计上很多方法写的过于冗长,并且每台电梯的run方法中写的不够精简,导致误差很容易出现,不过也有可能是出现了大量的新建对象导致的误差,这个是第七次作业我才发现的。

 

BUG方面:

本次作业没有出现bug,唯一的问题就是电梯运行过程中出现了误差,主要原因来自于线程wait和notifyall以及运行过程中执行代码所导致的误差积累。

 

三、第六次作业分析:IFTTT文件监视器

度量:

度量上pathchange方法中由于监控目录的情况中,需要进行一个for中嵌套for的遍历,再加上很多的条件判断导致复杂度较高,而scan方法中我原本采用的是一步一步的判断,例如先看格式,在看数字范围等等,这样导致了if的嵌套,在下次作业我觉得可以进行改变,一个check方法进行所有的判断,便可以有效降低复杂度。

 

类图:

类图方面,InputHandler一个线程,Output两个线程,每条IFTTT指令一个监控线程,另有一个测试线程用来进行文件的相关操作。本次程序通过wrap安全文件类来代替了所有的File操作,保证其线程安全。通过文件快照来扫描发生的改变并且与IFTTT的判断条件一一比对,将触发结果输出到文件。

 

UML协作图:

 

 

问题及不足:

问题主要在于本次作业中,有两种设计方法,一个是一条IFTTT指令一个线程,一个是一个监控对象+监控条件一个线程吗,这样可能导致的是由于线程过多和重复扫描,使得时间片过短的情况下,来不及进行所有的判断,从而落掉部分触发指令。

 

BUG方面:

本次作业被查出了bug,来自于由于多线程调度导致的一些IFTTT线程没有监控到文件的变化,初步猜测是扫描时间片过短导致的。在测试他人程序时,主要采用的策略是分析代码,由于多线程作业结果的不确定性,通过控制台输出以及文件信息的比对更能较好的看出问题,测试数据也没有刻意的构造偏难怪的数据,大部分是基本功能的测试,小部分来自于大量数据,对多线程性能进行测试。

 

四、第七次作业分析:出租车调度

度量:

度量上复杂度过高的是GUI中的一个方法,我也无能为力,块嵌套深度中search函数是在一个4*4的区域进行条件判断,所以首先两层for嵌套,再加上每个点上可能存在不止一辆出租车,以及条件判断有效性,导致复杂度较高,虽然代码上行数很少,但是也是一个可以优化的问题。

 

类图:

本次类图方面,采用了将100个出租车放入同一个线程TaxiSquad中,以保证行进的同步性。并且调度器和出租车群通过共享实时的地图快照进行出租车的派遣和调度,总共拥有GUI线程,出租车群线程,调度器线程和输入线程。这样做的主要原因是避免由于线程过多导致的误差和不同步。

 

UML协作图:

 

问题及不足:

由于上次作业出现的问题,这次刻意避免了线程过多导致的时间误差,将100个出租车放入同一个线程,这样的结果有好有坏,好处在于同步控制十分简单,将100个出租车看作一个对象进行统一更新,过程中不会发生多线程所导致的问题,比如有的出租车到达某个端点但是某个出租车没有,在派单,抢单上就会出现问题。但是看作一个线程在一定程度上违背了多线程的意义,虽然仍然有GUI,输入,调度和出租车群这几个线程,但是出租车之间并不是并发的。有利有弊。

 

BUG方面:

本次作业出了一个小问题,就是在抢单过程中,判断了是否已经抢过单,但是加信用度的时候忘记判断,导致多次抢同一单每次都加了该出租车的信用,在输出信息时就看出来了问题。这个属于本人编程过程中的粗心大意,下次一定注意。在找别人BUG时,主要是随便跑了跑大样本测试数据,然后通过文件输出自己判断他的分配策略是否合理正确。并且深入代码,找到分配错误的原因和源代码片段。

 

五、心得体会:

多线程之路感觉自己慢慢摸到了门道,从对象锁到方法锁,从wrap包装类到学习已经处理好的线程安全类,收获很多。

不过这几次作业也都花费了相当多的时间,连续熬夜感觉身体被掏空,并且多线程的作业难以测试和debug,导致在互测中出了或多或少额错误

希望能够顺利完成后几次作业,结束OO之旅

posted @ 2018-05-01 17:23  Retr0  阅读(190)  评论(0编辑  收藏  举报