面向对象第二单元总结:多线程的迷

  习惯了直线型的过程式编程思想,面向对象编程已经是很有难度了。而多线程之间运行的扑朔迷离比单线程更是让人摸不到头脑。

第五次作业:多线程电梯调度

设计策略:

  1、要求实时输入输出就要使用多线程,前两次的一次性输入策略不能再使用。我的想法是使用动态数组,通过引用同一个动态数组,输入线程往数组中添加请求,处理线程从中取出请求进行处理。

  2、我先想如果是单电梯调度,1中的思路就差不多了,三电梯只需要处理线程按照一定规则把动态数组分成三份。然后再添加三条电梯处理线程就可以了。

经典的OO度量:

类图及点评:

  也许是因为一次次添加完善的原因,整个系统变得极其庞大。本想改进第三次作业的调度机制,不在调度器里处理请求,但是由于修改的时候脑子不够用了,逻辑出现了问题。最终还是沿用了第三次作业的调度功能。并且是在电梯线程中处理导致程序可读性极差。好在这样处理简单粗暴,条理清晰(反正自己能想明白)。

协作图:

设计分析:

  电梯线程里负担太多工作,不够简洁。

测试:

  自己本地只构造了几个简单样例,没有什么问题。公测自己测试也没有什么问题。互测过程中对方并没有给我测试(公测都没得测)。我拿到的代码也十分优秀,虽然按照分支树测了好几个点也没什么问题。

第六次作业:IFTTT

设计策略:

  借鉴了群里讨论的逐个遍历两次来寻找变化的思路,对每一个任务都构造了一个线程。并根据任务调用summary和detail类的写文件方法,为了同步数据给这些方法都加了synchronized修饰词。

经典的OO度量:

类图、协作图及评价

  主要在监控线程里判断变化和处理,所以监控线程比较庞大。另外在document类里提供了多个测试线程可能用的方法。启动测试线程后,由于是一次性输入所有任务,所以输入方法并不是线程,每输入一个任务,启动一个监控线程,定期扫描监控对象,当测试线程里调用方法改动监控对象时,监控线程会进行判断和处理。

设计分析:

  本次作业的多个监控线程之间如果不是同一监控对象,则无数据共享,detail和summary的输出文件方法也用synchronized修饰。所以基本实现了数据安全。而对于相同监控对象的多个监控线程对线程安全考虑不足,有待改进。

测试:

  公测有几个点未通过,似乎是程序莫名修改了监控对象的名称,导致结果不符合。互测的时候找到了对方几个输入和输出格式的问题,但对方的功能没有什么问题。

第七次作业:出租车初体验

设计思路:

  初始化了100个出租车线程,然后根据输入构造请求线程来处理请求。

经典的OO度量:

类图、协作图及点评

  taxi类继承了guitaxi,新增了许多属性和方法,出租车线程里根据状态随机运动。map类里加载了地图文件。input类为主程序入口,里面启动了100辆车并根据每个输入请求构造请求线程。请求线程记录三秒窗口中抢单的出租车,并根据排序结果选择出租车接受服务。

设计分析:

  100辆出租车相互独立,每个请求线程也互不干扰。所以线程安全基本可以保证。

测试:

  由于作业实现线程过多,导致程序运行时堆内存不足,结果只记录了抢单的出租车信息,没有继续输出选择的出租车。而本地测试时,测试一个简单的请求时得到了正确的结果。这次互测的任务按照分支树没有找到功能性bug,其格式处理也十分正确。

心得体会:

  1、多线程设计似乎十分复杂,需要多考虑才能完美处理数据安全。

  2、严格来说,这三次作业不是很好,首先是因为对于共享数据保护不是十分到位。没有在设计时就妥善考虑;其次在设计思路上还是依赖于习惯的单线程直线思路,对于多个线程之间的协作考虑过于简单;最后在于时间上安排不妥,debug的时间占实现时间比例不够,有时虽完成了作业,却也遗留多个bug。

  3、以后的设计希望能严格遵守设计原则,多线程的数据共享也能考虑的更完善,希望下一次会更好。

猜你喜欢

转载自www.cnblogs.com/sumalefu/p/8982108.html
今日推荐