第五到第七次OO作业总结

经过这三次的OO作业实验,主要学习了java多线程的实现。

首先是多线程的电梯系列,既上次总结性作业中提到自己会改自己的实现方式,这次自己就在自己改的电梯的实现方式上受益。

先说一下以前电梯的设计方式:因为只有一个电梯,所以我并没有吧调度器和电梯的工作分开。所以我的一个schedule类就显得特别的臃肿,大概在四百行左右,这也包括我自己设计的思路不清晰导致的,运用了大量的判断的模式。

改进之后的电梯的设计方式:首先是调度器和电梯的部分的功能实现了分开,调度器只负责根据电梯的运行状态向电梯的请求队列里面增加请求,电梯只负责自己的运行,和每到一层楼检查自己的队列里面是否有捎带的问题。

因为第四次作业里面一共有三辆电梯,很明显第一种设计方式是很难实现的。

分开了了之后,多线程电梯的思路就比较清晰,按照指导书推荐的设计模式一步一步来就好了

首先构建一个托盘类,这个托盘其实是维护的一个请求的队列,用户不断的添加电梯的请求进入队列,调度器不断扫描请求队列跟电梯的队列,向满足条件的电梯队列中增加请求。

然后是电梯的运行方式在大体上没有改变,可能就是电梯的运行队列里面就少了很多判断(同质)。

在单线程的电梯里面我的同质请求的判断是由电梯的队列来判断的,但这次我把同质请求的判断移到了总的托盘的调度器的调度里面,通过引入了个灯的类来判断同质(其工作方式跟现实生活类似)。当请求进入托盘里面的时候,就能判出是否是同质请求。

然后最重要的问题就来了,就是多线程的冲突问题。

1.我这套灯的系统,开关灯的时候会发生冲突

2.对于我的托盘队列,请求加入托盘和请求派发到各个电梯的队列,这个部分会发生冲突

3.对于电梯的运行没到一层楼之后会扫描自己的队列,看是否能有捎带的请求,但是自己的请求队列可能正在被派发新的请求

4.就是调度器向电梯派发请求的时候,电梯也在运行状态会随时改变

这就是这次作业yao要解决的主要的问题

1.灯的冲突解决比较简单,主要在开关灯的地方加上synchronized方法,就能实现开关灯的同步问题了。

2.托盘请求队列的增长和减少的实现也比较简单,只要在请求的入队的方法,和调度器派发的方法的地方加上synchronized就可以了。

3.电梯空闲扫描自己的队列,和调度器向请求队列中添加请求的解决方式跟2类似

4.对于电梯派发和电梯的运行,自己在写的时候并没有考虑到这个问题,因为没太弄清楚要怎么锁一个对象,而且那个对象还在运行(当时还只是了解到synchronized的方法)。

然后想到了当请求扫描电梯状态的时候,电梯的状态都不应当改变,所以我建立了一个权限类,当做电梯与调度器之间的信息沟通,调度器在扫描电梯状态的时候,会获得电梯的权限,这时候电梯都不能改变自己的状态,等到电梯扫描完所有的电梯状态之后,并完成托盘队列一次扫描之后,在释放电梯的使用权限,让电梯改变自己的状态。

对于电梯来说,只要在自己要改变状态的时候,比如楼层加一,状态的改变的时候,会把自己的权限得到,改变状态完成之后便把自己的权限释放。

这个实现方式虽然看起来复杂,因为当时自己并不知道有lock的方法,现在只要在每一个电梯里面加一lock就行了,不用单独建立一个static的权限类,来解决扫描电梯状态和电梯运行之间的问题。

在测试中,自己的程序没有被测出bug,测出了对面的bug,主要是错在捎带的问题上,是同时对同一电梯输入ER操作,但是顺序是87654321,它不会将最后一条请求捎带。除此之外,有些捎带的请求也无法正常处理。

下面是我这次作业的类图:

 

 这次类图就是比较复杂了,因为电梯的调度器,调度器,输入部分都要对请求队列进行操作,而且我还引入了灯的系统导致,并且扫描器也要操作多个类所以导致结构十分的复杂和混乱。

可以看出扫描队列的类的方法特别复杂,自己看了代码好像是因为将电梯的所有信息都保存了起来,使用的判断条件也十分复杂,我想其实可以把判断的方法,分成两个方法,可能是自己的判断方法太复杂了吧。

总的来说这一次作业还是比较困难的,因为第一次接触多线程,需要学习的东西很多。这次作业大概一共花了四天多的时间。以后就会好一点了,万事开头难,然后中间难,最后结尾难嘛。

文件系统是我写的最难受的一次作业,自己都会觉得无效。

这次的作业因为有了上次多线程的经验所以线程冲突方面还是比较好解决的,毕竟扫描器每隔一定的时间才会去扫描请求队列,冲突也比较少。

这一次作业的主要问题还是在于功能的实现,包括整个架构的实现。我接下来回会重点说一下我做此次作业辛酸的心路历程。

首先是监视器的问题,到底把什么作为一条监视器的条件,到底是一个条件,一个文件,还是一个IF语句,最后最终考量之下,把一个IF语句建立了一个监视的线程。

第二个问题就是实现的问题。我的构想是引入工厂的模式,把工厂作为一个单件,我想的是把四种类型的触发器作为工厂里面的原件,四种触发后执行的行为作为另一个工厂里面得原价,然后在一个总的任务工厂里面把触发器和执行器组装作为一个任务输出,但是后来实现的时候发现,执行器的接口很难统一,所以只好把执行器放在每一种触发器里面,所以我的触发器一共有四个.java文件。

但是周二下午的时候我发现,我把监视目录的东西忘了加进去,所以我几乎重写了四个触发器的代码,这里我也体会到了工厂模式的弊端,就是如果一个地方要修改,那么修改的工作量是十分巨大的,虽然使用工厂模式会使得这个程序的架构十分的简单。由于我是临时加入的检测目录的行为,已经顾不了代码的质量,也就加入了很多的if语句,所以我每一个触发器里面都十分的臃肿,本来运用工厂模式会挺简单的。

在接近ddl的时候,我发现我的程序对删除文件不能正常相应,最后发现是我自己的设计问题,忽略了,renamed和path-changed中以前不存在,现在存在的这一条要求,这就导致我在作业结束前一个小时,还在改这一部分,好在在前半个小时改完了。

最后此次的作业被测出了两个bug,算是万幸了,因为自己以为会测出来很多bug的时候,这些bug其实只能算作自己的理解问题吧。

一个是我的其中的监控对象问题,我限制了只能输入十条语句,因为我以为的监控对象是一个IF一条。但是其实是每一个文件或者目录才算一个对象。另外一个是recover触发两次record的问题,因为当文件移到另一个文件夹中去的时候,他的监视范围也会改变,而我并没有改变,所以会出现触发两次的问题。

测试对方出现的bug中,对方的检测目录功能没有实现,检测文件的功能没有出错,被扣了不少的分数。

这是此次作业的类图:

 从这次的结构来看,架构还是挺清楚的,但是由于这一次的作业是临时赶出来的,所以每一个类里面其实结构都挺复杂的,单个文件和目录基本上进行的监视是通过if进行判断,并没有把监视文件和目录的相似性体现在代码中,所以每一个类的圈复杂度特别高(不能赶ddl啊,特别是周二几乎是重新开始写的)。

从这次作业中,我明白了,最好提前开始准备OO,别等到周一晚上才开始看题,这种拖延就使得我的此次作业完成的十分痛苦,周一晚开始构思,然后开始写了一部分数据的处理,和架构,周二下午开始重新写到四点多赶电工实习报告,睡了三个小时开始边上课边debug,写说明文档,下午的时候继续debug完善程序,在截止前10分钟交了上去。那一周真的过得是十分难受。以后在周末的时候一定要开始写,才不至于影响到自己的其他科目。

第七次作业是第一个出租车的第一次作业,这次的作业相比于前两次的作业,相对简单,另一方面也是由于有了前两次作业的铺垫,对于多线程的理解也更加的深刻。

这一次的作业实现方式上面跟多线程的电梯有类似的地方,其中唯一不同的是,请求的派发分为两个步骤,一个是汽车自己要去扫请求队列,然后发出抢单的申请,三秒之后,请求根据判断的条件来选择发出抢单请求的出租车中最适合的那一辆,然后派给它,这个判断条件的过程跟第一次类似,必须要锁住相应的出租车的状态,这个地方我就是在每辆出租车里面加的一个锁。

这一次的冲突分析跟电梯请求的的冲突分析类似。这里我也发现了一直对多线程存在的问题,这个问题也很难解决,就是下面这种情况:(也没有很好的解决办法)

队列的入队和队列的出队还有出租车对请求队列的扫描这三个过程是互斥,加锁的方式就能解决,但是100出租车对队列的扫描却不是互斥的,如果把扫描也synchronied的话,100辆出租车对队列的扫描也变成顺序的,当请求很多的时候,程序运行的效率就很低,所以我一直在向如何实现100辆车对队列的扫描是不互斥的,但是对队列的出队入队是互斥的呢?

此次作业的测试中,因为虽然有gui但是,还是不太好去debug,被测出来一个bug,关于设计这方面没有被测,所以只能自己去分析。

在给对面的测试中,对面的功能完善,格式测完之后,发现对起点终点相同的请求,他的程序没有判出来,其余的方面都挺好的。

这个是这次作业的类图:

 

 这次的类图很简单,因为是第一次作业。但是我写的某些类却出了一些问题,可能是因为结构复杂,但是都是一些处理输入上面出现了复杂度较高的问题。一些可以通过构造另一个方法处理,但是还是有一个在我看来结构已经很简单的输入也出了问题,是地图的输入,我想可能是判断太多了,但是在我看来这些判断是必不可少了,一个是文件是否存在要判断,文件的行数要判断,每个字母的合法性要判断,所以圈复杂度就比较高。

 

总的来说通过这几次的作业,自己的能力提高了一些,但是远远不够,代码的规范,耦合度,设计的原则方面很少考虑,希望自己能在接下来的作业之中,努力的用这些原则来规范自己的行为。

转载于:https://www.cnblogs.com/im73/p/8974422.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值