2019_BUAAOO_第二单元总结
第一次作业:单部多线程傻瓜调度电梯
设计策略
本次作业我才用的是生产者消费者模式,创建一个RequestList类,将输入线程InputThread作为生产者,负责将请求放入RequestList;将电梯线程ElevatorThread作为消费者,负责从RequestList中取出请求。通过synchronize实现两个线程的互斥访问。
代码分析
类图
方法复杂度
类复杂度
BUG分析
此次作业在公测与互测中均未发现BUG,也没能在互测阶段hack成功。
第二次作业:单部多线程可捎带调度(ALS)电梯
设计策略
第二次作业仍然可用生产者消费者模式,总体与上次一样。调度策略也按照指导书的说明使用ALS调度。在实现上,由于每次都通过调度器发送开关门、上下乘客的信号较为麻烦,因此我通过在电梯中增加一个Passenger请求队列,用来表示在乘坐电梯的人,电梯每到一层,就检查Passenger队列,若是有人的目的楼层在当前楼层,则电梯会自动开门,然后将此人从Passenger队列中剔除。当Passenger队列为空时,通过调度器调度电梯;否则,电梯会自己运行并在每一楼层更新Passenger队列,直到Passenger队列为空停止。这样的实现方法相比电梯的所有操作都由调度器管理来说要简单许多,但这样写就相当于电梯本身就带有调度器的功能,使得这两个类的功能有所重合,这不符合面向对象的设计原则,因此并不推荐这样的写法。
时序图
代码分析
类图
方法复杂度
可见,Elevator类中有不少方法的复杂度都比较高,这也是此次设计中的不足之处。
类复杂度
BUG分析
此次作业中,我在线程退出的问题上存在BUG。本次作业我有三个线程,分别为电梯,调度器和输入线程,而调度器作为调度线程,理应在其他线程都已结束的情况下,再进行退出,可我的代码中,只要输入线程已经结束,那么调度器就会结束,整个程序就直接结束。这样会导致电梯中还有乘客未走出电梯,但电梯已经停止的情况。BUG的解决办法就是设置一个电梯线程的结束标志,当电梯线程输入线程都结束后,调度器才会结束。
此次作业未发现他人BUG。
第三次作业:多部多线程智能(SS)调度电梯
设计策略
仍然使用生产者消费者模式。
此次作业我共启动了六个线程。分别为三个电梯、一个输入线程、一个调度器、一个楼层检测线程。每个电梯都有属于自己的ElevatorList与TransferList,即电梯请求与换乘请求,电梯只负责从ElevatorList中取出请求并按照请求将乘客送往指定位置,当乘客到达目的地后,楼层中就会出现该乘客,将该乘客的id加入到floorPassenger中。输入线程作为生产者,读入请求并将其加到RequestList中。调度器负责从RequestList中取出请求并进行分析,若是不需要乘客换乘的请求,则直接将请求加入到对应电梯的ElevatorList;若是需要乘客换乘,则将该请求拆分为两个请求,将第一个请求加入到对应电梯的ElevatorList,将第二个请求加入到对应电梯的TransferList中。楼层检测线程,则是不停检测floorPassenger与TransferList,只要有楼层中的乘客id与TransferList中的id相匹配,则将TransferList中的请求删除,并将该请求加入到对应电梯的ElevatorList,这样就可以解决需要换乘请求的先后顺序问题。
由于此次作业我沿用了上次作业的代码,因此在实现可捎带功能的部分,设计原则依然存在与面向对象思想相违背的情况。
时序图
代码分析
类图
方法复杂度
类复杂度
这次作业由于要实现的功能更多,因此许多方法和类的复杂度都比较高。
BUG分析
此次作业中未发现线程调度与设计上存在的BUG。
总结
根据SOLID原则进行整体评价:
- SRP(单一责任原则):由于在二三次作业中电梯都覆盖了部分调度器功能,因此不符合。
- OCP(开放性原则) :后两次作业都沿用了之前的代码,代码可拓展性较好。符合。
- LSP(里氏替换原则) :这三次作业只继承了Thread类,电梯对象的创建是通过参数设置完成的。符合吧。
- DIP(依赖倒置原则) :符合吧?
- ISP(接口分离原则) :本单元作业只用了Runnable接口。
体会与收获
本单元重点集中在多线程上。
第一次作业,是实现一个最简单的多线程。主要是为了熟悉线程的基本操作,例如线程的创建、结束等,只要了解synchronize关键字的用法,很容易就完成此次作业。
第二次作业,本质上与第一次作业没有太多区别,但在功能实现上更加复杂,而且严格限制了CPU_TIME_LIMIT与REAL_TIME_LIMIT。因此,此次作业对于我们在线程调度上有一定要求,不能再像第一次作业那样暴力轮训,必须通过wait与notify等操作实现线程调度,否则就会出现TLE。此外,由于捎带功能的出现,导致代码更加复杂,若是出现BUG,也要求我们具有有一定的多线程调试能力。
第三次作业,才是真正的综合实践:多部电梯,各个电梯可达楼层不同,速度也不同,可承载人数也不同,需要乘客等待、换乘,不再如同前两次作业般的傻瓜调度。要完成此次作业难度不是特别高,但想要真正优化好,就需要有良好的调度策略:调度器需要根据电梯内人数按照一定优先级分配请求,必要时还要让不用换乘的乘客实行换乘提高效率的目的。
总的来说,经过本单元的锻炼,在多线程设计方面一定会有很大的提升。
期待下个单元的主题。
2019_BUAAOO_第二单元总结的更多相关文章
- OO第二单元作业小结
前言 转眼已是第九周,第二单元的电梯系列作业已经结束,终于体验了一番多线程电梯之旅. 第一次作业是单电梯的傻瓜调度,虽然是第一次写多线程,但在课程PPT的指引下,写起来还是非常容易:第二次作业是单电梯 ...
- BUAA面向对象设计与构造——第二单元总结
BUAA面向对象设计与构造——第二单元总结 第一阶段:单部傻瓜电梯的调度 第二阶段:单部可捎带电梯的调度 (由于我第一次写的作业就是可捎带模式,第二次只是增加了负数楼层,修改了一部分参数,因此一起总结 ...
- 我永远爱着OOP——第二单元作业总结
第二单元的电梯真是愉♂快呢,多线程编程作为java编程OOP中的重要组成部分,通过这一个单元的学习,我也是有了很多全新的认识 那么下面就先例行一下公事 三次作业分析 第五次作业 设计分析 实现的电梯是 ...
- 2019OO第二单元总结
(1)设计策略 电梯第1次作业是一个傻瓜调度电梯,使用先来先服务原则,不用考虑捎带(可以认为电梯的载客量为1),因此比较简单,调度器用一个队列就可以. 使用生产者-消费者模型,输入线程是生产者,电梯是 ...
- oo第二单元作业总结
oo第二单元博客总结 在第一单元求导结束后,迎来了第二单元的多线程电梯的问题,在本单元前两次作业中个人主要应用两个线程,采用“生产者-消费者”模式和共享数据变量的方式解决问题.在第三次作业中加入多个电 ...
- OO第二次博客作业--第二单元总结
第一次作业 1. 设计策略 第一次作业,一共三个线程,主线程.输入线程和电梯线程,有一个共享对象--调度器(队列). 调度的策略大多集中到了电梯里,调度器反而只剩下一个队列. 2. 基于度量的分析 类 ...
- 第二单元电梯调度作业 By Wazaki
figure:first-child { margin-top: -20px; } #write ol, #write ul { position: relative; } img { max-wid ...
- OO第二单元总结(多线程的电梯调度)
经过第一单元作业的训练,在做第二单元的作业的时候,要更加的有条理.但是第二次作业多线程的运行,带来了更多的运行的不确定性.呈现出来就是程序会出现由于线程安全问题带来的不可复现的bug.本单元的作业也让 ...
- OO第二单元电梯线程系列总结作业
电梯系列第一次作业 功能描述: 傻瓜电梯无需考虑超载捎带 线程模式: Producer-Consumer Pattern 思路: 第一次作业是一个傻瓜电梯,分别有一个生产者生成电梯指令(也就是Inpu ...
随机推荐
- 使用git把本地目录传到远程仓库
需求: 要把本地不为空的一个目录和远程现有的一个仓库关联 步骤如下: git init //生成.git目录 git add . //把当前目录里的文件加入到暂存区 git commit -m '上传 ...
- 【转】让EntityManager的Query返回Map对象
在JPA 2.0中我们可以使用entityManager.createNativeQuery()来执行原生的SQL语句.但当我们查询结果没有对应实体类时,需使用entityManager.create ...
- Java中的String、StringBuilder以及StringBuffer
https://www.cnblogs.com/dolphin0520/p/3778589.html
- Redis从入门到精通【centos下的安装】
上传redis 到服务器 解压并重命名 然后yum -y install gcc-c++ zlib zlib-devel pcre pcre-devel openssl openssl-devel 然 ...
- django学习笔记-模板层
模板层 将Python嵌入到HTML中. 模板简介 将HTML硬解码到视图并不是那么完美原因如下: 对页面设计时也需要对python代码进行相应的修改,模板可以不就行python代码修改的情况下变更设 ...
- spring-mvc访问本地html文件
项目中要用到在线预览word文档,刚开始考虑是要将word转成pdf文件,然后再直接在浏览器打开pdf文档即可, 但是项目部署在Linux下,在网上搜了一下没有找到合适的方法, 后来项目组讨论用POI ...
- bat实现固定时间循环抓取设备log
背景:测试时需要实时抓取android设备log,但是一份log抓取过来非常庞大(有时超过500M+,编辑器都打不开,还得找工具进行分割,甚是蛋疼),查看也非常不方便. 解决:基于上述情况,与其之后进 ...
- OPPO A3在哪里打开usb调试模式的详细教程
当我们使用电脑通过数据线连接上安卓手机的时候,如果手机没有开启Usb开发者调试模式,电脑则无办法成功读到我们的手机,这时我们需要找方法将手机的Usb开发者调试模式打开,这里我们叙述OPPO A3如何开 ...
- PHP取一算法
一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大 ...
- Vue之展示PDF格式的文档
事实上有很多种在前端展示PDF格式文档的方法,小编也用过好多种,例如有<iframe>.<embed>和<object>这些标签,但是在Vue项目里,这些方法都不能 ...