BUAA_OO第二单元总结性博客作业——多线程电梯架构
一、设计策略
在第一次作业时,我刚第一次接触多线程这个东西……于是乎对于第一次VIP直上直下一次只接一个人的电梯,我借鉴了指导书中为我们提供的架构,设计了一个输入线程和一个电梯线程,并设置了一个中间类RequestQueue,开一个队列来存放异步输入的请求,并保证这个类是线程安全的。在main类中仅仅只做了new了这几个类并且启动输入线程以及电梯线程的工作。当电梯运行时,GetRequest线程读入请求,并存放到RequestQueue类中的队列中,Eletavor线程run方法中的while循环一直检测队列中的请求,若有请求则取出第一条请求执行(sleep相应的与移动楼层有关的时间,输出开门、进人、关门的语句,再sleep相应时间,再输出与出人有关的语句)。当GetRequest中读到为null的请求时,将Request中的flag置flase。当Elevator检测到RequestQueue中的flag为flase,并且队列为空,则中断while循环,接下来线程也就结束运行,程序结束。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。第二次作业相较于第一次作业增加了需要捎带的需求,按道理在第二次作业就加入调度器模块是比较符合课程组要求的,但是……我在写第二次作业时为了更充分地利用第一次作业的架构,并没有对“输入-队列-电梯”这个三层的架构做过多的更改(除了加入了wait()与notify()避免暴力轮询带来的CPU时间过长)。于是我对Elevator线程中的runelevator方法做了一些修改,在类中增加了一个名为inelevator的arraylist(不需要线程安全),在RequestQueue中加入了遍历队列并移出匹配出发楼层的请求并返回的方法(名为getfromthisfrom)。对于runelevator方法,原本的暴力直接sleep移动速度乘以移动楼层的方法不可用了,我只能一层一层地移动电梯,输出"ARRIVE-x"。我仍然使用了第一次电梯作业中取出队列的第一条指令进入runelevator方法运行的机制,并且在第二次作业中可以按照指导书的说法将这条指令看作是主请求。(虽然我不怎么愿意这么叫它,因为它的作用仅仅是确定电梯中没有人时需要运行的方向,其他跟捎带指令并没有区别),在电梯开始移动后,在到达每一层时均调用RequestQueue中的判断是否有能上电梯的人加入inelevetor队列(这就是所谓的捎带请求)或是inelevator队列中是否有需要出电梯的人(这一步中主请求与捎带请求并无区别,只要到达楼层与当前楼层相等,就让他出来)。
在这种情况下电梯运行状态中很重要的一项就是运行方向的判断。如果要按照原本的主请求设计模式,对于类似“1-FROM-10-TO-1;2-FROM-11-TO-1”这样的指令。满足为了性能的优化……
