OO第二单元总结
这一单元作业是围绕电梯调度进行展开,并引进了多线程的概念。与第一次作业比较类似,作业难度也是逐渐推进,从最开始的单部电梯先来先服务(傻瓜式调度),到之后的单部电梯可稍带调度,到最后的多部电梯分楼层调度。下面分别说明并分析一下三次作业的设计结构。
第一次作业
作业概述:程序的输入流会不定时随机投放若干用户请求,用户的请求包括出发楼层和目标楼层,电梯没有容量限额,在规定时间上内完成所有请求。
这次作业的意图是让大家对线程有一个初步的认识(因为用户请求不定时投放,电梯强制在线必须要用线程才能搞定),共享对象的加锁保护以及线程之间的同步控制。单论本次作业的难度还是很低的,我大概用了三四个小时就完成了本次作业。
设计策略
由于第一次作业只有正确性要求,没有性能分,所以我也就没费工夫想如何优化调度hhh,就直接写了个先来先服务的模型。尽管电梯很愚蠢,看着有人经过也不捎带一下。。。但是在正确性上有十分充足的保证。
实际上,第一次作业得电梯调度就是最经典得生产者消费者模型,整个代码也就分为了三个部分,两个线程。主线程也就是第一部分用来接收用户请求,也就是生产者,另一部分是共享对象用来存储请求队列,最后一部分是电梯线程用来从请求队列中获取请求,也就是消费者。
代码分析
设计图

各个类得作用请见设计策略。也没什么可具体分析的了。
度量分析


可以看出这次设计的层次还算不错,各个指标都没有特别高的。当然这是因为这次作业比较简单。
Bug分析
分析自己程序的bug: 这次作业没有bug。
分析他人程序的bug: 高工这块没有互测部分,但是也和同学私下互相讨论过,测试方法就是写几个测试样例看看结果是否正确,以及看看代码内部是否有明显的逻辑漏洞。均为发现错误。
第二次作业
作业概述:这次作业和第一次作业基本一样,也是一部电梯,同时没有人数限制。唯一的区别就是要完成捎带调度。当然说是增加了调度算法,但是实现起来还是十分容易的。只需要每次到达一层楼的时候看一眼该楼层是否存在相同运行方向的等待的人。
设计策略
基本和第一次作业一样,同样都是两个线程,分别是主线程读取用户请求,子线程运行电梯。共享队列实际上是内置在电梯中的,但是为了方便理解,我还是单独写了一个共享队列的类,但是并没有做成线程,只是经了一下手立马就发给了电梯的内置队列(自己骗自己hhh)
代码分析
设计图

度量分析


Bug分析
分析自己程序的bug:似乎还是没有bug。。。这次虽然还是没有bug,但是因为有了性能分,所以并不是满分。我也只是实现了指导书中推荐的捎带算法,没有考虑其他更好的优化方法。实在是打不过优化大佬们。。。
分析他人程序的bug:在和其他小伙伴交流的时候还是没有发现什么bug,有的同学是把所有请求都添加到电梯中,也就是不管这个人是向上走还是向下走,你先进来,先和我绕一圈回头我再送你去你的楼层。虽然很不符合实际,但是似乎比常规的捎带方法最终的时间还要短。。也是有点意思。
第三次作业
作业概述:这次作业有了很大的升级,分为了三个电梯,每个电梯可以停留的楼层还不一样,有的人还必须要换乘才能到达指定的楼层。各个电梯的速度也不一样。
设计策略
这次的设计结构不同于上述两次作业,要复杂很多。由于这个有三个电梯也就是有多个消费者,所以并不能像之前那样把共享对象写在电梯里面,而是要有一个调度器对所用请求指定电梯后,在电梯内部再进行二次调度,也就是可稍带调度。所以总体上是有五个线程,一个主线程接收请求,一个子线程作为主控用来处理请求队列的分发,剩下三个是电梯线程,用来处理每个电梯的调度以及电梯的运行。但实际上由于这里有的请求非常的麻烦,需要不同电梯协同工作才能完成,比如说请求要从20->3楼,而只有A电梯能停留20楼,只有C电梯能停留3楼。所以这种情况我的处理办法是先让A电梯停留在一个AC都能停留的楼层,比如说5楼,然后这时把请求发到5楼同时修改成一个新的请求为5->3楼,这样再把这个新的请求发送给主控的共享队列。也就是说除了Main线程是生产者以外,电梯内部也可以生产新的请求。至于是如何调度的,我的调度器十分简单,就是先判断是否有直达电梯,并将请求发给最近的直达电梯。如果没有可用的直达电梯(两种情况,直达满了,或者就是需要中转的)就给一个最近的电梯。电梯到每一层的运输规则都是写死的,比如如果能直达就直达就ok了,但像A电梯不能到3楼,所有通过A想去3楼的就都会送到5楼。显而易见,我这种方式绝对不优,甚至有时候很愚蠢。
代码分析
设计图

度量分析



可见Request类的sendRequest()函数的度量值很高,这是因为里面进行了非常对的if判断,来分类到底要给哪个电梯。
Bug分析
分析自己程序的bug:依旧没有bug。
分析他人程序的bug:我看的大多数小伙伴的代码bug主要集中在程序结束判断上。当然不同人写法不一样,但大体来讲不能简单通过Main线程的输入结束来判断是否要关闭主控线程,必须要等所有的电梯都结束了同时没有输入了才能关闭。
总结
先从课程作业体验上讲一下,总体感觉这一单元的体验要比上一单元好一些,代码写得也顺利很多,最多用一天就都能写完(难道是我进步了???)。
在说说多线程编程的体会吧,总的来讲前两次作业不需要太多的思考,简单加个同步锁就ok了。但是在第三次就了一些更深的感受,首先多线程debug就很不同,单步调试基本没啥用,print会更直接。其次就是加锁的艺术,有的时候全部加上锁肯定没问题,但是性能会下降很多,但是如果减少锁的范围可能又会出现不同步带来的bug,所以需要好好权衡和设计这块。
最后感谢老师和助教的帮助和指导!
OO第二单元总结的更多相关文章
- oo第二单元作业总结
oo第二单元博客总结 在第一单元求导结束后,迎来了第二单元的多线程电梯的问题,在本单元前两次作业中个人主要应用两个线程,采用“生产者-消费者”模式和共享数据变量的方式解决问题.在第三次作业中加入多个电 ...
- OO第二单元优化博客
OO第二单元优化博客 第五次作业没有性能分,但是,我在这一单元的宗旨就是写一个日常生活中 最常见的那种电梯,所以第五次我没有写傻瓜电梯,而是直接写了个\(look\),和第六次基本相同. 总计一下lo ...
- 【OO学习】OO第二单元作业总结
OO第二单元作业总结 在第二单元作业中,我们通过多线程的手段实现了电梯调度,前两次作业是单电梯调度,第三次作业是多电梯调度.这个单元中的性能分要求是完成所有请求的时间最短,因此在简单实现电梯调度的基础 ...
- OO第二单元小结
OO第二单元小结 一.三次作业代码分析. 1.第一次作业 第一次作业是单部电梯的傻瓜调度,由于其过分傻瓜,所以第一次作业我只有两个类,一个main,一个电梯,main类负责不断从输入流中读取命令,如果 ...
- OO第二单元多线程电梯总结
OO第二单元多线程电梯总结 第一次作业 设计思路 Input为输入线程,负责不断读取请求并将读到的请求放入调度器中. Dispatcher为调度器,是Input线程和Elevator线程的共享对象,采 ...
- 电梯也能无为而治——oo第二单元作业总结
oo第二单元作业总结 一.设计策略与质量分析 第一次作业 设计策略 在第一次作业之前,我首先确定了生产者--消费者模式的大体架构,即由输入线程(可与主线程合并)充当生产者,电梯线程充当消费者,二者不直 ...
- 2020北航OO第二单元总结
2020北航OO第二单元总结 前言 本单元考察基于多线程的电梯调度问题,成功让我从一个多线程小白到了基本掌握了使用锁来控制线程安全的能力,收获颇多(充分体验了迷茫地de一个又一个死锁bug的痛苦). ...
- OO第二单元——多线程(电梯)
OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...
- OO第二单元作业总结【自我反思与审视】
第二单元作业的完成史,就是一部心酸的血泪史…… 多线程的出现为我(们)打开一片广阔的天地,我也在这方天地摸爬滚打,不断成长!如果说第一单元之前还对Java语法有所了解的话,那么这单元学习多线程则完全是 ...
- OO第二单元(电梯)单元总结
OO第一单元(求导)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉理解和掌握多线程的思想和方法.这个单元以电梯为主题,从一开始的最简单的单部傻瓜调度(FAFS)电梯到最后的多部 ...
随机推荐
- 基于docker 如何部署surging分布式微服务引擎
1.前言 转眼间surging 开源已经有1年了,经过1年的打磨,surging已从最初在window 部署的分布式微服务框架,到现在的可以在docker部署利用rancher 进行服务编排的分布式微 ...
- 一行代码实现数组去重(ES6)
ES6中新增了Set数据结构,类似于数组,但是 它的成员都是唯一的 ,其构造函数可以接受一个数组作为参数,如: let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3]; ...
- jenkins + supervisor + ansible 实现netcore程序的多机一键部署
上一篇我们简单的说到了使用jenkins+supervisor实现了一个单机版的多副本部署,但是在更多的场景下还是需要netcore程序的多机一键部署,那么多 机器间如何分发呢? 肯定不能使用scp这 ...
- C#开发APP,ToolBar控件在Smobiler中的使用方式【附案例源码】——Smobiler移动开发平台
控件说明 底部工具栏控件. 效果演示 其他效果 该界面为仿淘宝UI制作的一个简单的UI模板,源码获取方式请拉至文章末尾. 特色属性 属性 属性说明 Direction(相对布局) 容器主轴方向. Fl ...
- 引用provinces.js的三级联动
第一次写随笔 应该写的不是太好 请多多见谅 我这次是在网上发现了一个三级联动 也是给新人一个福利 这个是你需要新建个 JavaScript 文件 并复制到你新建的文件里面 var pr ...
- SSM+Maven+MySQL实现简易的挂机修仙页游
一段时间没有写过SSM的项目了,最近重新整合框架做了一个小Demo 学Java的萌新可以看一看:大佬呢,欢迎指出不足! 我一直钟爱挂机类游戏,同时也喜欢修仙和武侠小说,于是突发奇想,自己搞一个小游戏? ...
- java监听器简述
监听器的概念 所谓监听器就是对内置对象的状态或者属性变化进行监听并且做出反应的特殊servlet,并且也需要在web.xml文件中进行相关配置. 内置对象的状态变化:初始化和销毁,也就是说当内置对象初 ...
- 为View设置左右切换动画
本文同步自http://javaexception.com/archives/64 问题: 近期的需求中,碰到了一个view切换动画的需求.要实现的是点击按钮,从左到右滑动view,左边的view消失 ...
- ubuntu下svn的命令使用
Subversion的官方网站是:http://subversion.tigris.org/ SVN简介 SVN(Subversion)是一个自由.开源的项目源代码版本控制工具.目前,绝大多数开源软件 ...
- 2018-09-13 代码翻译尝试-使用Roaster解析和生成Java源码
此文是前文使用现有在线翻译服务进行代码翻译的体验的编程语言方面第二点的一个尝试. 参考Which framework to generate source code ? - Cleancode and ...