第二单元的问题是写一个关于电梯调度的程序。

需要模拟一个多线程实时电梯系统,从标准输入中输入请求信息,程序进行接收和处理,模拟电梯运行,将必要的运行信息通过输出接口进行输出。 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

主要锻炼学生的多线程程序编写能力。

由于需要实时的输入和输出,我们不得不采用多线程。

在这个单元中任务仍然被分为三个小任务:

①完成单电梯(随时允许输入)

②单电梯+(楼层增加负层,必须使用比先来先服务更加高效的算法)

③多电梯调度(guess,也有可能加上重量限制等)

一、调度算法设计

单电梯的调度算法:

我在网上寻找调度算法后发现,网上大多的算法采用的都是静态算法,几乎没有动态算法。所以,我自己设计一个算法(或者说是参照实际使用中电梯的运转方式设计的算法),如下:

①查看该楼层是否有请求(包括进电梯和出电梯),有则开门转②,否则转③

② 让请求的人进出,并进行输出,所有请求进的人将这些人的出电梯请求同时加入电梯的请求序列中。关门转③

③沿电梯运动方向查看是否有任意类型的请求,如果有请求则向该方向运动一层转④,否则改变方向查看请求。如果在另一方向上有请求,则想这一方向移动一层转④。如果两个方向都没有请求则进程休息(wait),等待唤醒,唤醒后转④。

④如果不在输入任何需求则结束,否则转①。

多电梯的调度算法:

多电梯我觉得可以在原来的基础上进行修改,在调度器分配请求时通过某种方式将请求分给不同的电梯,然后每台电梯按照单电梯的调度算法进行运行即可。由于本人的多电梯的调度算法效率比较低,所以这里就不多赘述,可以参考其他同学的多电梯调度算法。

二、程序分析

 对每次的程序使用MetricsReloaded进行oo度量,使用diagram描绘类图

重要符号意义说明:

  • ev(G)基本复杂度是用来衡量程序非结构化程度的.
  • Iv(G)模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。
  • v(G)是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数。
  • LOC: Line of Code
  • NCLOC:Non-Commented Line Of Code 

P1

oo度量

 

  LOC NCLOC
Elevator 183
169
Main 9 9
Midlist 26 26
OrderClass 46 42

 电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第1张

diagram类图

电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第2张

 

P2

oo度量

  LOC NLOC
Elevator 219 206
Main 11 11
Midlist 33 33
OrderClass 46 62

电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第3张

 

diagram类图

电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第4张

 

 P3

oo度量

  LOC NLOC
Chart  62
62
Elevator  307 278
Entry  8 8
Main  12 12
Midlist  367 322
Orderlist  46  42

电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第5张

 

类图

 

 电梯调度编写(oo-java编程)(等待指导书发布后内容补充) 随笔 第6张

优点:在第一次作业的时候就做好了基础的调度设计,后续的修改都不大。

缺点:功能不够独立,在新需求出现时,常常要重新独立出一部分功能。设计时缺少借口等这类设计,导致一修改需求就会违背oo的设计原则。

 

三、分析自己程序的bug

第一次作业中,程序结束的控制计较容易出bug,因为在程序结束输入的时候(ctrl+D),仅凭借队列里是否有未服务的对象是不够的,还需要有一个判断标志,在电梯每次轮循后对输入是否结束进行判断,从而决定是否结束电梯线程。

第二次作业中,由于不能轮循(因为太占cpu时间),所以必须使用wait/notify方法,这个时候需要考虑好线程有没有可能会死锁,如何才能保证不死锁以及如何控制线程结束。(这三个问题是第二次作业中比较重点的bug/问题)

第三次作业,由于程序难度的增加,程序的复杂,轮循和,进程意外退出,进程没有被唤醒再次成为问题的关键。在这一次中,我最后应该将轮循和进程退出可能的情况进行列表推演,当当靠脑子想这件事情是很不靠谱的!

四、寻找他人bug(我不做互测)

根据这次多线程的特点,应该着重考虑多线程的死锁、轮循这两个问题,着重分析他人代码中占用的位置。而且多线程的bug不一定能够触发,所以可能要多试几次。

五、Applying Creational Pattern

这次重点的模式应该是单例模式(第一次使用)以及观察者模式(应该在第三次作业使用)。单例模式被我使用参数传递的方法代替了,实际上使用单例模式会更符合设计结构。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄