OO第二章总结

OO第二章总结

电梯作业终于结束了!!! 这三周作业用多线程模拟搭建电梯的运行,我从开始对多线程的一无所知到结束时的能够完成一些多线程任务的水平,进步还是蛮大的,尽管过程有点艰难。

一、复杂度与UML图分析

第一次作业

UML

Person类在本次作业没有用到,我只是预留了一个扩展类。MainClass类作为启动,PassengerQueue类是共享资源类,也就是生产者消费者模式的那个传送带。Input是生产者,Elevator是消费者。

复杂度分析

电梯类的WMC很高,也就是循环复杂度很高,代码有个地方进行了重复循环,有待改善。

第二次作业

UML

类的构造和上次基本没有区别。

复杂度分析

第二次作业问题和上次一模一样(代码复用的结果

第三次作业

UML

由于限定了电梯的种类,我便建立了三个电梯类,来是实现类别不同,这种方法有点笨重,可以进行抽象出三种类的公共之处作为一个类,这是有待完善的地方。

复杂度分析

三个类的代码是可重复复用的,写法过于臃肿了。

代码量

二、自己程序的BUG

程序的bug主要包括RTLE,CTLE以及单线程的逻辑问题。

1. RTLE

RTLE全称Real Time Exceed,在这三次作业中,评测机所给的Real Time都很大,一般调度是不会让程序RTLE的,产生的主要原因就是程序的线程无法停止。

无法停止有两个原因:一个是程序没有设置终止条件,无法停下来;另外一个就是可能程序里面出现了死循环,比如:电梯卡在某一层一直开关门,或者电梯在-1和1层游荡等就会导致电梯一直运行,而无法停止。

解决也很简单,在程序的结束增加输出的语句来判断Run方法是否结束,然后在每一个循环里面增加输出即可。

2. CTLE

这个就很常见了。。。。(在我的程序里面

CTLE全称CPU TIme Exceed。CTLE发生也就一个原因,就是发生了轮询,也就是一直进行判断是否满足条件,导致CPU一直在运行。

这样的bug说排除很简单,也可能很难。简单就是他产生原因很简单也很明显,说难就是它的出现可能是多线程随机的问题,很难复现。

我的排除方法就是仔细分析单线程的逻辑问题。毕竟轮询就是一个循环,一直在询问,那么程序里面一定会出现类似死循环的情况。在第三次作业里面通过这种方法,找到了bug出现的原因。另外一个方法就是努力去复现,因为有的死循环,可能是在某一个情况才出现,然后导致轮询。复现方法和RTLE一模一样。

3. WA

wa的情况就自己的程序一般逻辑的问题,很容易去复现,找到问题,解决即可。一般都是写代码时的马虎与不注意。

三、互测

互测找到别人的bug,我是靠自己写代码时的经验与经历,来构造特定的bug然后hack别人。

四、设计策略

1. 单部可携带ALS电梯

第一次作业的设计就很简单,只是一部电梯。我采用了生产者和消费者模式。

由于输入是实时的,我便设置了一个输入线程作为生产者,将请求添加到主请求(调度器)里面。单部电梯从主请求里面获取一个请求,然后运送,运送过程中如果遇到顺路的请求就顺路接到电梯。

两个线程的公共资源是主请求,在使用时需要对齐进行加锁,保证唯一使用。

2.多部可携带ALS电梯

第二次作业的设计是在第一次的基础上增加动态电梯线程创建和人数的限制。电梯线程的逻辑基本都一样。

这次电梯线程增加,一个输入线程作为生产者,多个电梯线程作为消费者,在每一个电梯在进行对主请求的写操作的时候,都需要加锁来保证写的唯一性。所以相比第一次作业这次电梯线程逻辑,对每一个写操作进行加锁。基本逻辑是没有任何改变的。

3. 多部可携带ALS电梯

第三次作业相比第二次作业增加了很多的限制条件,限定了电梯的可停靠楼层,限定了电梯的种类等,同时需要满足动态增加电梯的需求。

这次作业我实现了我前两次作业一直想要实现的一个Person类,用来扩展输入接口提供的Request类。因为前两次都没有必要去实现,也就没有实现,但这次电梯需要考虑进行换乘,所以就需要扩展Request类来增加能够更新需求的状态的操作。在实现Person类之后,我发现一切都变的和第二次作业如此的相似,我需要做的只是把需要换乘的人们在第一阶段之后进行更新状态即可。同时由于对电梯的可停靠楼层的限制,我不得不重新对线程的同步问题进行重新设计。

重构了线程终止的条件,同时改变线程等待的条件,并在每一个新增加需求之后唤醒每一个电梯线程,在没有需求的时候,便让他们进行休息。

可扩展性

第三次作业的可扩展性,可以支持动态删除电梯,可以动态启动电梯线程,只要是关于电梯的新的需求,需要改变的仅仅的顶层的一部分,对于电梯的基本运动逻辑是基本不需要任何改变的。

五、心得体会

对于多线程的设计模式,设计方法,设计思路等有了充分的了解,在多线程并发的能力上有了显著的提高。从开始的一无所知到后来能清晰的认识到电梯的运行过程,并精确快速找到bug,真的收获很多。但是也是能够清楚的认识到,其实多线程还有很多很多东西有待学习,电梯结束了,但是对多线程的学习刚刚起步。

三次作业的迭代明显比第一章的作业迭代要简单很多,并不需要很多的重构,很多代码都是能够重复使用的。而且在第一次作业的时候,我已经预料到在迭代的过程中,输入接口所提供的的Request类是需要被扩展的,才能满足需求,也就预留了很多小的设计在里面以方便后来扩展使用。

 

 

猜你喜欢

转载自www.cnblogs.com/donkey55/p/12719935.html