OO第二次课程总结分析

  前几回的做业都是单线程的,整体来讲和之前的思惟模式和调试等存在着必定的挂钩,在设计上总体难度还不算太大,此次开始了多线程编程,难度能够说是质的飞跃,构思上所考虑的不止一点两点,在总体的基础上还要考虑线程的同步安全等问题,下面针对三次做业的分析来谈谈在多线程编程上所犯的错误和获得的收获编程


 

1、多线程电梯数组

1.设计策略安全

       做为多线程的第一次做业,又恰逢清明假期,能够有相对充足的时间来学习多线程的相关知识和进行构思(能够说这个清明假期过得很是揪心了),由于有了前面两次电梯的积累,此次关于同质和捎带的问题并未花太多时间(可是考虑前面的代码可塑性太差,此次就进行了重构,但核心思想没变),大部分时间用在了构思三部电梯的调度和安全问题上。多线程的设计与单线程不一样,在构思实现逻辑的同时还要决定开多少个线程,每一个线程之间的交互影响、线程安全问题等,复杂程度大大提高。在经历了多天的思考以后,我共设计6个线程(分别为主线程(Main)、输入线程(Inputhandler)、调度器线程(Scheduler)及三个电梯线程(Elevator))。共有4个请求队列(一个总的,3个各自电梯的)。多线程

各个线程的工做以下:架构

  • 主线程(1):其余线程的实例和启动
  • 输入线程(1):在收到输入结束符以前持续接受控制台输入,将有效请求(其中无效和同质都不算有效)放入请求队列
  • 调度器线程(1):当总的请求队列不为空或输入线程未结束时,不断扫描总的请求队列,根据三部电梯状态和分配原则来将请求分配给合适的电梯
  • 电梯线程(3):当本身的请求队列不为空或调度器线程未结束时,不断扫描本身的请求队列,根据电梯状态和请求来执行相应的动做

  关于线程同步控制的考虑,由于请求队列会涉及到加入请求、删除请求、从队列中取出请求及获取队列大小等操做,这都是线程不安全的,所以在对队列的操做上我都上了锁,一样,电梯状态会有改变和获取的操做,一样都加了锁。学习

2.程序结构分析测试

度量分析ui

类图spa

 

 

sequence diagram线程

 

  我的以为总体架构还算满意,各个线程分工较明确,只是在具体实现时有部分代码显得臃肿,还未能作到方法功能单一,部分方法用了太多的条件分支,在代码重用性方面有些欠缺,代码的可塑性不强。

3.bug分析

  公测有四个样例没过,主要仍是栽在了调度线程的问题上,分配请求的方法发生了错误,在判断电梯运动量上未作到安全,考虑不够周全,致使多个点爆了,另外时间永远是一个头疼的问题,公测终究仍是被报了时间的错误。互测被找了一个格式错误,对格式边界的把握仍是不够。

   测他人时仍是先从格式下手,再测一些基本功能的实现(先观察代码看必要的地方有无加锁,再针对性测试),而后从边界状况来找到是否符合预期,最后就是用大一点的数据去测。

 


 

2、IFTTT

1.设计策略

  老实说,此次做业的难度比上次的要大,毕竟上次的做业有以前的做业的积累,而且给的时间相对较长,但此次做业不只时间相对少,还涉及到文件系统,光是理解做业需求就花了挺长时间,致使最后做业完成的很糟糕。此次的构思基本就是针对一个做业开一个线程,每一个线程监控每份做业相应的某个触发器和某个task,而且在建立线程的开始就为每一个做业建一个状态快照,线程实时扫描文件,并实时生成更新快照,比较先后快照的不一样看是否触发了相应的触发器,根据相应的触发器而作出相应的动做。各个线程以下:

  • 主线程:处理输入,如队列,线程实例和启动
  • Detail线程:处理detail这个任务
  • Recover线程:处理recover这个任务
  • Summary线程:处理summary这个任务
  • TestThread线程:提供测试接口
  • Watch(监控)线程:根据触发器不一样让哪一个任务执行

  关于线程安全的考虑,对文件的操做会致使线程不安全,所以这块利用锁来实现同步,保证同一时刻只能有一个线程在对文件操做,避免应线程不安全而致使难以预料的错误。

2.程序结构分析

度量分析

类图

sequence diagram

  此次的程序能够说写得很糟糕,因为时间的不足,没有考虑监控目录的状况,而且程序的主线程写了太多,显得很臃肿,应该将输入处理等移出,主线程只负责启动其余线程方为上策。同时,Safefile类忘记提供获取最后一次修改时间等方法。总之,此次的构思有些问题,程序结构设计的不是很合理。

3.bug分析

  此次互测被找的bug是最多的一次,由于没有实现目录的监控,这部分被找了bug,同时,recover也未能实现,致使被测了许多bug,也是对本身的反思吧,毕竟本身没有实现那部分的功能。

       此次互测就是针对几种触发器和几种任务的组合,一一进行几组测试,从而找出与预期结果相悖的点,针对找到的点,找到对应的代码,看关联的方法或其余,再针对地找其余bug。

 


 

3、出租车

1.设计策略

  由于出租车是相互独立的,互不影响,故考虑每辆出租车一个线程,每辆出租车都有各自的私有属性,都能进行抢单、运送等动做,且出租车之间没有交互,各自独立。同时由于每辆出租车要从抢单出租车中选出合适的,故每一个出租车都设了一个属于本身的请求队列,调度器负责为乘客选择合适的出租车,出租车负责将乘客送往目的地。所以,程序的线程以下:

  • 主线程:读入地图信息、声明静态常量、线程实例及启动
  • 输入线程:输入请求并将有效请求(无效、同质均不算)加入队列
  • 出租车线程(100):出租车的各类运行(随机跑或按最短路径跑)
  • 调度器线程:选出抢单出租车并进行派单

  关于线程安全的考虑,本次总的请求队列是一个共享资源,故是非线程安全的,在对队列的操做中都加了锁,由由于调度时要得到出租车的状态、信用度即位置等,因此在出租车的状态、信用度及位置等的set,get方法上均加了锁。

2.程序结构分析

度量分析

类图

sequence diagram

  此次程序的方法我尽可能地去写得很短,只实现某一个功能,其余部分各人认为写得算是比较简洁,但调度器的run方法仍是用了太多的循环和条件判断,致使度量变红,这一块应该改进,抢单能够另外用一个方法实现,而不用写在run里还有Taxi的判断走哪条路的方法复用性不够强,代码的相同地方过多,能够经过传目的地参数的方法进行此部分代码的复用。

3.bug分析

  此次交得急,没有写测试接口,被报了一个设计缺陷,同时由于gui中算最短路径的方法耗时太长,在输出时我用的是假时间,但gui上跑得较慢,由于这个缘由,接单和服务状态下车要比等待时跑的慢,被测试者找了bug,还有由于在遍历数组时条件判断不够充足,致使程序在必定间隔内输入的多条请求引起NULLpoint的crash。

  此次找bug为了能保证出租车必定能接到单,我找的时候让出租车初始位置从某个点出发,便于进行测试。

 


 

最后的心得体会

  经历过这最痛苦的三周,对多线程编程也有了本身的体会。在多线程电梯刚开始使用锁时,傻傻地锁住了sleep,致使线程之间不能并行,这个让我困惑了许久,后来逐渐缩小锁的方法的范围才解决。多线程的运行机制比单线程复杂得多,在动手以前要足够了解这种机制,否则真的发生了预料以外的后果你也会手足无措,因此事先设计构思、想好哪些资源须要共享,哪些须要同步,哪些线程是独立的,哪些是交互的,我认为这种考虑在多线程编程中是很是有必要的。

相关文章
相关标签/搜索