(一)第五次作业

一、设计思路

生产消费者模型,输入接口是producer,调度器是tray,电梯是customer。由于只有一架电梯,所以生产消费模型满足以下条件:

  1. 一个生产者,一个消费者
  2. 托盘不为空时,消费者可以取走请求。任何时候,生产者可以添加请求。(托盘无容量限制)

互斥:生产者——生产者,消费者——消费者。

同步:生产者至少生产一次,消费者才能消费。

互斥问题我给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原则:

  1. 单一责任原则:在电梯类里,有goUp,goDown,openDoor,closeDoor,peopleMove函数符合单一职责原则,但是operate函数在while循环里反复调用这五个小函数,条件比较复杂,显得臃肿。
  2. 开放封闭原则:作业二到三的扩展很方便,电梯的载客量和速度作为一个属性,增强了扩展性。
  3. 里氏替换原则:第三次作业里面A,B,C电梯是电梯类的实例,避免大量复用。但是由于电梯作业结构简单,三次都没有用到继承。
  4. 接口分离原则:没有用到接口
  5. 依赖倒置原则:调度器里有电梯的引用,电梯里有调度器的引用。

OO电梯作业总结的更多相关文章

  1. OO——电梯作业总结

    目录 电梯作业总结 程序结构与复杂度的分析 第一次作业 第二次作业 第三次作业 程序BUG的分析 互测 自动评测 有效性 总结 电梯作业总结 程序结构与复杂度的分析 第一次作业 1.设计思路 第一次作 ...

  2. OO第三次电梯作业优化

    目录 第三次电梯作业个人优化 前言 优化思路 一.调度器 二.电梯 第三次电梯作业个人优化 前言 由于个人能力有限,第二次电梯作业只能完成正确性设计,没能进行优化,也因此损失了强测分数,于是第三次电梯 ...

  3. OO第二单元——电梯作业总结

    前言 本单元作业主要以设计电梯来实现多线程编程.本章主要学习了如何使用多线程以及如何确保多线程安全,从电梯的调度策略中学会了如何简单地使用synchronized锁来控制线程安全. 首先,明确锁的两个 ...

  4. 从入门到不放弃——OO第一次作业总结

    写在最前面: 我是一个这学期之前从未接触过java的小白,对面向对象的理解可能也只是停留在大一python讲过几节课的面向对象.幸运的是,可能由于前三次作业难度还是较低,并未给我造成太大的困难,接下来 ...

  5. OO第二单元电梯作业总结

    目录 目录一.第一次作业分析设计策略基于度量分析程序结构二.第二次作业分析设计策略基于度量分析程序结构三.第三次作业分析设计策略基于度量分析程序结构四.分析自己程序的bug五.发现别人程序bug所采用 ...

  6. OO第一次作业总结

    OO第一次学习总结 1.第一次作业:多项式加法 从未接触过java的我,在从输入输出开始学了几天后,按照C语言的思路,写出了一个与面向过程极其接近的程序. 在这个程序中,存在两个类:一个是Comput ...

  7. 学会拒绝,是一种智慧——OO电梯章节优化框架的思考

    在本章的三次作业里,每次作业我都有一个主题,分别是:托盘型共享数据.单步电梯运行优化.多部电梯运行优化,因而电梯优化实际是第二.三次作业.虽然后两次作业从性能分上看做得还不错,但阅读其他大佬博客,我深 ...

  8. OO电梯系列总结与反思

    目录 前言 HW5 度量分析 UML类图与协作图 bug分析 HW6 度量分析 UML类图与协作图 bug分析 HW7 度量分析 UML类图与协作图 bug分析 SOLID原则 感想 前言 紧张刺激的 ...

  9. oo第一次作业

    前言: 这是一篇面向对象作业总结,作业内容是对多项式进行求导,一共有三个阶段,具体要求不详述,第一阶段只要求’+’连接coeff*x^pow的形式,第二次支持*连接的幂函数及三角函数,第三次则需要支持 ...

随机推荐

  1. app自动化定位:UIautomation的用法

    UIautomation定位的优点: 速度比xpath定位快,UIautomation是Android的工作引擎 缺点: 没有idea提示 UIautomation使用方法: AndroidDrive ...

  2. JNDI注入基础

    JNDI注入基础 一.简介 JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API,命名服务 ...

  3. WPF WPF中解决内存泄露的几点提示与解决方法

    http://www.cnblogs.com/LastPropose/archive/2011/08/01/2124359.html 一直以来用WPF做一个项目,但是开发中途发现内存开销太大,用ANT ...

  4. 使用SQL SERVER存储过程实现历史数据迁移

    今天讲下软件开发中最常见的历史数据迁移方式.在讲迁移之前,先简单介绍下几个基本概念. 1.什么是历史数据迁移? 简单直白地说:就是将一些创建时间比较久而且不常用的历史数据,存储到另一个地方(可以是另一 ...

  5. 洛谷P1309——迷宫(傻瓜DFS)

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...

  6. 手机UI自动化之显示点触位置(触摸轨迹)

    上期回顾:Airtest源码分析--Android屏幕截图方式 不管是用Appium还是Airtest,或是其他手机UI自动化工具,你是不是经常遇到这种情况,代码明明执行了click或swipe,怎么 ...

  7. Java基础系列(33)- 计算器

    package method; import java.util.Scanner; public class Demo09 { static double result; static String ...

  8. Shell系列(36)- for循环语法二简介及批量添加删除用户

    for循环语法二 for ((初始值;循环控制条件;变量变化)) do 程序 done 例子 例子-1 求和工具 需求:根据用户输入的数字,求1~输入所有数字的和 脚本: #!/bin/bash re ...

  9. SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践

    一. 前言 日志对于一个程序的重要程度不用过多的言语修饰,本篇将以实战的方式讲述开源微服务全栈项目 有来商城 是如何整合当下主流日志解决方案 ELK +Filebeat . 话不多说,先看实现的效果图 ...

  10. 配置 放上传文件的目录 apache(httpd)

    1. 确认服务器 开放8088端口 https://www.apachefriends.org/download.html 下载XAMPP for Windows,安装 2. 修改apache主配置文 ...