第二次博客作业

一、第五次作业相关分析


1.设计策略

​ 本次作业是多线程电梯,在我的逻辑中,电梯就遵循着自己的运行法则。所以电梯按照自己的状态不断运行,而在电梯运行的过程中,状态的改变可以根据灯来进行。调度器则负责对请求队列里的请求进行调度。这是大体的思路,此处就会产生很多多线程的冲突问题:队列的线程安全比较显然,故不再赘述。而在调度请求时,势必会产生获取电梯状态和电梯状态改变的矛盾。因为一个线程要读取电梯状态,一个线程改变电梯状态,所以电梯中部分代码块就需要用到同步。另外就是多个电梯需要读取和改变楼层灯的状态,所以楼层灯也需要进行同步。在清楚了这些以后,编码工作就变得相对而言轻松了,首先编写一些边缘的类,比如InputHandler,Request,Floor等类,再集中进行Scheduler、Elevator类的编写,就完成了代码阶段的工作。

2.度量信息及类图

​ 本次设计中,最大的问题就是类间的依赖性较大。比如电梯的可捎带判断等,这种方法本质上不应该属于电梯,但是为了编码的方便,还是将捎带问题的判断作为了电梯的一个方法。还有就是,对于返回私有属性的get方法,事实上应该是不可变对象,否则应该返回对象的克隆。在编码中这种类型的东西都并没有太过注意。

3.bug分析

​ 对于我自己,此处被找到了一个同时性的bug。因为对于我们的多线程而言,真正的并行是不存在的,所以就算理论上三个电梯是同时到达,也不会真正的同时。总会有先后,我的程序会因此将一些指令分配给运动量较小的电梯,由于多线程调度原因这个电梯会比其他理论上同时的电梯先到了一点,因而先分配了指令。

​ 对于别人而言,我分配到的那个人没有采用真实时间的策略,电梯因此也未用线程去实现,所以会出现很多时间上的bug,并非属于线程调度方面的典型bug,所以在此不再叙述。

二、第六次作业相关分析


1.设计策略

​ 本次作业是文件监测。大概思路就是每隔一段时间就提取监控区的快照,然后再对两个时间段的快照进行对比。此处我采取的方式是每个监控任务一个线程,该线程根据自己的任务类型、监控范围等信息,隔一段时间取一遍快照然后进行对比操作。每个监控线程之间少有联系,但是它们会共用一个方法提取快照,共同记录summary和detail。所以此处记录summary和detail的线程需要进行同步,防止产生写文件的冲突。另外,文件操作也需要同步,而我采取的策略是把文件操作全部封装为静态同步方法,用类锁来进行同步,同时将获取快照的方法也放在里面,从而能极大程度上避免多线程的文件操作造成的冲突。

2.度量信息及类图

​ 本次设计中,较优秀的一个改进就是类之间的耦合减少了,当然一部分原因是各种类型的监控任务比较独立。但是与此同时带来的一个问题是FileAttrs中存储了很多无关信息,从设计角度来说其实这是一个缺陷。

3.bug分析

​ 本次是我被发现的bug较多的一次,后来发现bug的原因大多出自于监控文件夹。由于这一部分是后加的写的比较仓促,并未发现在有多个操作同时进行时判断重命名以及路径改变逻辑的一个小问题,导致出现了两个bug。

​ 本次中我拿到的代码写的比较好,而且还使用了课上所说的工厂模式、单例模式等。一开始找到了几个bug,是理解上的问题,后经协商修改了。其实到了现在,只要是写的相对还不错的代码,大概对同步的使用已经有了基本的了解,至少能保证不出或少出错误。我大多只是用我在自己写程序时候可能出现线程问题的测试用例来测试别人。

三、第七次作业相关分析


1.设计策略

​ 本次作业是出租车调度。某种程度上我这次借鉴了多线程电梯的设计,因为他们有很多相似之处,例如都有一个对象在运行,都有请求,都需要一个调度器去分配请求。所以本次我的出租车就类似于电梯,他有自己的状态,以自身状态为依据决定如何运行以及切换下一个状态。所以我也像电梯一样,把出租车自身状态或属性改变的过程进行了同步。与电梯不同的是,此次要管理的出租车较多,所以引入了TaxiManager去管理所有的出租车。而对于一些其他问题,例如图的数据结构的选择。由于本次所有点的度最大是4,所以一定是稀疏图,因此决定用邻接链表存储边,并用SPFA求稀疏图的最短路(本次中相当于bfs)。

2.度量信息及类图

​ 注意到TaxiInfo类的构造函数参数过多,针对这种问题网上给出的解决方法是使用Builder模式,定义一个内部类Builder,成员变量与外部类一致,为外部类中每一个可选变量定义一个类似的setter方法,只不过是会返回自身,Builder的构造函数返回外部类的实例,这样就能通过链式调用来构造了。

3.bug分析

​ 我自己的bug其实是测试者有些没搞清问题,讲了很久没讲通就各退一步了,不认为自己有bug。

​ 我测试的那个人只有一个很简单的小问题,是指导书上的要求没有注意到。其余的我都是尽量按照代码编写者的逻辑去理解他的输出的,感觉并没有问题。至于测试的一个策略就是可以先通过几个指令将出租车全部汇聚到一个地点,再进行其他测试。

四、心得体会


​ 感觉从第五次作业开始,设计上已经形成了自己的一个固定的模式,相对而言这个过程没有之前那么头疼。对于线程安全,在写第五次作业时其实还是朦朦胧胧的,直到第一版写完还是。后来仔细上网查了查,才明白一些关于类锁和对象锁的知识,又因此重写了部分第五次的代码。折腾过这次之后,第六次、第七次作业在线程安全上的考虑就能较为顺利的体现在代码上。考虑线程安全的过程主要还是考虑各个类之间的协作关系,再从伯恩斯坦条件入手,得出那些需要做线程同步措施的类。

​ 对于设计原则,我感觉这是在设计阶段就应该想好的问题。而遵循了设计原则的代码编写起来相对而言难度较小,此处的难度较小并不是指作业的难度变小了,而是每个部分的工作量变少了,只需要专注这一部分的编写就好,协作等顶层问题留给其他线程去解决。以上就是我这几次作业的感受。

猜你喜欢

转载自www.cnblogs.com/mingming97/p/8974804.html