OO电梯作业总结
(一)第五次作业
一、设计思路
生产消费者模型,输入接口是producer,调度器是tray,电梯是customer。由于只有一架电梯,所以生产消费模型满足以下条件:
- 一个生产者,一个消费者
- 托盘不为空时,消费者可以取走请求。任何时候,生产者可以添加请求。(托盘无容量限制)
互斥:生产者——生产者,消费者——消费者。
同步:生产者至少生产一次,消费者才能消费。
互斥问题我给get和put函数加了方法锁。
二、调度策略:FAFS傻瓜电梯
遵循先到先服务,所以调度器作用很小,只是完成托盘的功能。调度器内部有一个请求队列,还有put和get方法。输入接口和电梯是两个线程。输入接口每收到一个请求,即时加入到调度器队列里。电梯每执行完一个请求,向调度器索要下一个请求。
三、类图
四、度量分析
五、Bug分析
如何结束电梯线程?
调度器里面有一个close变量标志是否收输入结束了。输入接口(使用put函数)传入为null的请求时,调度器会将close变为有效。电梯执行完最后一个任务,get下一个请求。如果此时请求队列为空,且close有效,电梯也结束线程。
但最开始,我把结束电梯的条件写错了,只要close有效就会结束。但可能还有请求没来得及读进调度器队列。正确的get函数写法是,如果请求队列为空且close无效,说明输入没有结束,还要等待后面的请求,就先wait。不再满足wait条件的时候,如果队列仍为空且close变为有效了,就结束电梯。
第二个问题是,输入结束时,我没有调用put方法,而是单独调用一个end函数改变close状态。这样会有一种情况:最后一个请求还在put函数里没有进入请求队列,但后面被紧接着调用了end函数把close置位了,此时也是请求队列为空,close有效,最后一个请求就没有执行。解决方法是,结束输入时,依然调用put函数,传入一个为null的请求。Put函数有synchronized修饰,必须一次一次调用。
六、互测bug
此次作业比较简单,没有发现互测的bug。
(二)第六次作业
一、设计思路
仍然是生产消费者模型,与第一次作业类似。
二、调度策略:ALS可捎带电梯
在调度器里增加了一个flush函数。电梯用get方法得到第一个请求,称为主请求。在去主请求fromfloor的过程中不捎带,从from到tofloor时,每到达一层,用flush函数向调度器索要可以捎带上的请求。捎带条件是,捎带请求与主请求同方向,且捎带请求的fromfloor在电梯当前floor到destination之间。Destination的初值是主请求的tofloor,在电梯每次收到捎带请求的时候更新为主请求和捎带请求tofloor里面更远的那个。
一开始我的电梯在到达主请求fromfloor的时候也可以捎带,但是捎带条件极其复杂,使用的不是destination,而是highestFromFloor,highestToFloor这些变量作为运动的终点。考虑到对第三次作业的可拓展性,我放弃了复杂的捎带策略,但也因此没有拿到性能分。
三、类图
四、度量分析
五、bug分析
从第一次作业直接移植进出电梯的方法,出现了同一个人进两次电梯的问题。所以我在电梯类里面设置了两个请求队列,一个是还没进电梯的请求,一个是在电梯里面的请求,解决了这个问题。
如果在0秒出现两个从1层进电梯的请求,我最初的写法不能捎带上第二个请求。在电梯刚到达一层,和开门之后都向调度器索要可以捎带的请求,解决了这个问题。
六、互测bug
没有发现同组的bug。调度策略越慢,越不容易出现bug,传统的捎带策略最保险。
(三)第七次作业
一、设计思路
在调度器里,给每个电梯设置一个队列。输入接口传入一个请求的时候,调度器根据分配策略分配给一个电梯队列。
二、调度策略
调度器分配请求的原则是,优先分配给能直达的电梯,都能直达的时候优先级A>B>C。否则调用transfer函数,进行换乘分配。
电梯从调度器属于自己的队列里取请求,和查看捎带请求。
关于换乘:
将换乘请求分成两个,分配给两部电梯。
其中一个难点是,确保完成换乘的第一站,再开始第二站。我新建了一个TransferRequest类保存换乘请求的id,负责第一站的电梯,第二站的电梯。将一个换乘请求分配好,就设置一个对应的TransferRequest,存入换乘队列。当完成第一站请求(即人走出电梯)的时候,把它从换乘队列删除(transfered函数),执行第二站的电梯检测到队列里没有这个换乘请求了(检测函数为transfering函数),才能执行第二站。
三、类图
四、度量分析
五、bug分析
我设计初期的bug围绕着一个问题:电梯get第一个请求的时候,何时wait,何时结束运行?
Wait的时机是,电梯的请求队列为空且输入没有结束,或者输入结束电梯请求队列不为空但所有都是没完成第一站的换乘请求。相对的,每次输入新请求和完成换乘第一站的时候,都要notify。
结束运行的时机还是,请求队列为空,且输入关闭。
六、互测bug
最常见的问题是多步电梯造成的线程冲突。有些同学让三部电梯同时从一个请求队列里抢请求,多个函数都会修改请求队列,但没有严格互斥。除了请求队列,三部电梯还有其他共享数据,对所有共享数据访问的时候产生混乱。
(四)个人总结
我发现电梯的调度策略越简单,可拓展性就越强,从第二次到第三次作业,我写的非常快,因为捎带的调度策略完全不用修改,电梯类只增加了载客量,速度这两个属性。
但是如果想达到比较有效的优化,就要从LOOK模式转变成SCAN模式,工作量指数型增长。
SOLID原则:
- 单一责任原则:在电梯类里,有goUp,goDown,openDoor,closeDoor,peopleMove函数符合单一职责原则,但是operate函数在while循环里反复调用这五个小函数,条件比较复杂,显得臃肿。
- 开放封闭原则:作业二到三的扩展很方便,电梯的载客量和速度作为一个属性,增强了扩展性。
- 里氏替换原则:第三次作业里面A,B,C电梯是电梯类的实例,避免大量复用。但是由于电梯作业结构简单,三次都没有用到继承。
- 接口分离原则:没有用到接口
- 依赖倒置原则:调度器里有电梯的引用,电梯里有调度器的引用。
OO电梯作业总结的更多相关文章
- OO——电梯作业总结
目录 电梯作业总结 程序结构与复杂度的分析 第一次作业 第二次作业 第三次作业 程序BUG的分析 互测 自动评测 有效性 总结 电梯作业总结 程序结构与复杂度的分析 第一次作业 1.设计思路 第一次作 ...
- OO第三次电梯作业优化
目录 第三次电梯作业个人优化 前言 优化思路 一.调度器 二.电梯 第三次电梯作业个人优化 前言 由于个人能力有限,第二次电梯作业只能完成正确性设计,没能进行优化,也因此损失了强测分数,于是第三次电梯 ...
- OO第二单元——电梯作业总结
前言 本单元作业主要以设计电梯来实现多线程编程.本章主要学习了如何使用多线程以及如何确保多线程安全,从电梯的调度策略中学会了如何简单地使用synchronized锁来控制线程安全. 首先,明确锁的两个 ...
- 从入门到不放弃——OO第一次作业总结
写在最前面: 我是一个这学期之前从未接触过java的小白,对面向对象的理解可能也只是停留在大一python讲过几节课的面向对象.幸运的是,可能由于前三次作业难度还是较低,并未给我造成太大的困难,接下来 ...
- OO第二单元电梯作业总结
目录 目录一.第一次作业分析设计策略基于度量分析程序结构二.第二次作业分析设计策略基于度量分析程序结构三.第三次作业分析设计策略基于度量分析程序结构四.分析自己程序的bug五.发现别人程序bug所采用 ...
- OO第一次作业总结
OO第一次学习总结 1.第一次作业:多项式加法 从未接触过java的我,在从输入输出开始学了几天后,按照C语言的思路,写出了一个与面向过程极其接近的程序. 在这个程序中,存在两个类:一个是Comput ...
- 学会拒绝,是一种智慧——OO电梯章节优化框架的思考
在本章的三次作业里,每次作业我都有一个主题,分别是:托盘型共享数据.单步电梯运行优化.多部电梯运行优化,因而电梯优化实际是第二.三次作业.虽然后两次作业从性能分上看做得还不错,但阅读其他大佬博客,我深 ...
- OO电梯系列总结与反思
目录 前言 HW5 度量分析 UML类图与协作图 bug分析 HW6 度量分析 UML类图与协作图 bug分析 HW7 度量分析 UML类图与协作图 bug分析 SOLID原则 感想 前言 紧张刺激的 ...
- oo第一次作业
前言: 这是一篇面向对象作业总结,作业内容是对多项式进行求导,一共有三个阶段,具体要求不详述,第一阶段只要求’+’连接coeff*x^pow的形式,第二次支持*连接的幂函数及三角函数,第三次则需要支持 ...
随机推荐
- TCP协议和套接字
一.TCP通信概述,逻辑连接就是三次握手 二.客户端和服务端实现TCP协议通信基本步骤 1.客户端套接字对象 Socket 2.服务端套接字ServerSocket 客户端补充完整代码:除了创建各自的 ...
- [CVE-2020-1956] Apache Kylin远程命令执行漏洞复现
Apache Kylin是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区. ...
- 【第三篇】- Git 工作流程之Spring Cloud直播商城 b2b2c电子商务技术总结
Git 工作流程 本章节我们将为大家介绍 Git 的工作流程. 一般工作流程如下: 克隆 Git 资源作为工作目录. 在克隆的资源上添加或修改文件. 如果其他人修改了,你可以更新资源. 在提交前查看修 ...
- excel中if函数的用法
IF函数有三个参数,语法如下: =IF(条件判断, 结果为真返回值, 结果为假返回值) 第一参数是条件判断,比如说"A1="百度""或"21>3 ...
- 基于django2.2的网页构建
安装django pip install django==2.2 建一个在线商城的项目 django-admin startproject pyshop 启动项目 python manage.py r ...
- Java入门准备:Java开发环境的安装与卸载
Java的三大版本 JavaSE:标准版 JavaME:嵌入式开发 JavaEE:企业级开发 JDK(Java Development Kit):Java开发者工具包 JRE(Java Runtime ...
- Django学习day14BBS项目开发1.0
每日测验 """ 1.简述auth模块功能 2.简述项目开发流程 3.简述bbs表设计 """ 内容回顾 auth模块 "&quo ...
- win7下python2.7安装 pip,setuptools的正确方法
windows7 下 0.先安装python2.7.13 32位:https://www.python.org/ftp/python/2.7.13/python-2.7.13.msi 64位:htt ...
- Feign超时不生效问题
使用Feign作为RPC调用组件,可以配置连接超时和读取超时两个参数 使用Feign配置超时需要注意:Feign内部使用了负载均衡组件Ribbon,而Ribbon本身也有连接超时和读取超时相关配置一. ...
- 华为云计算IE面试笔记-FusionSphere Openstack有哪些关键组件,各组件主要功能是什么?三种存储接入组件的差异有哪些?
1. Nova:在OpenStack环境中提供计算服务,负责计算实例(VM,云主机)生命周期的管理,包括生成.调度和回收.Nova不负责计算实例的告警上报(FC管). 2. Cinder:为计算实例提 ...