OO第二单元博客作业——电梯系列
一、锁与进程
waitqueue为等待队列,elevatorqueue为电梯中人的队列
1. 第一次作业
两个进程:InputThread和Elevator
设置的锁有waitqueue和elevatorqueue(均为class类)。输入请求时,waitqueue上锁,电梯寻找目标楼层和人员变动时锁waitqueue和elevatorqueue两个类。为了防止死锁,均采用先锁waitqueue再锁elevatorqueue。
synchronized (waitQueue) {
synchronized (elevatorQueue) {
2. 第二次作业
第二次作业有不定量个进程,Elevator类可新建若干个进程,每个elevator对应一个elevatorqueue,只有一个waitqueue队列。
锁与第一次作业无区别。
3. 第三次作业
有一个总的waitqueue和ABC三个分waitQueue,其余同第二次作业,不同之处在于使用了调度器,调度时锁住总waitqueue和要将请求添加入的ABC分waitQueue中的一个。
二、调度器设计
第一、二次作业没有设计调度器(虽然写了scheduler类但最终并没有依靠调度器进行电梯运行),第二次作业采用的是电梯抢人策略。
Elevator的运行策略为:若ElevatorQueue中有请求则获取第一个请求的toDoor,若没有请求则获取WaitQueue第一个请求的fromdoor,若两个队列都没有请求且程序未停止输入,则waitQueue.wait();
第三次作业
调度策略:
由于电梯运行速度A<B<C,故采用能用C就用C,其次是B,其他是A,判断条件为起始楼层和终点楼层是否满足条件。
if (Arrays.asList(arriveC).contains(request.getFromFloor()) &&
Arrays.asList(arriveC).contains(request.getToFloor())) {
queue = waitQueues.get(2);//C类电梯
}
else if (Arrays.asList(arriveB).contains(request.getFromFloor()) &&
Arrays.asList(arriveB).contains(request.getToFloor())) {
queue = waitQueues.get(1);//B类电梯
}
else {
queue = waitQueues.get(0);
}
想法简单,未使用换乘策略,但效率却很高(狗头保命)
三、架构设计可拓展性
第三次作业
本次作业由3种thread类InputThread,Scheduler和Elevator;2种容器WaitQueue,ElevatorQueue;和MainClass构成。他们的组织结构如图所示。

通过Scheduler将waitQueue中各请求进行调度,放入各个子waitQueue中,再使用哪部电梯先到达乘客所在楼层乘客进入哪部电梯,即将子waitQueue中的请求转移到该电梯的请求队列中。
UML类图
下图为生成的uml类图。

UML顺序图
下图为此次大作业的uml顺序图。

可拓展性
三次作业的迭代过程并没有重构,各类间实现了高内聚低耦合,若要继续添加新的要求也可完成,可拓展性较好。
四、bug
-
在第二次作业中被测试数据9的random180s开始同步运行卡了tle,修改bug方法是random等待较短一段时间,这样其他人就可以同步上电梯。
-
第三次作业互测中被边界测试数据卡了tle(很多个2-17楼运行),修改方法是采用电梯换乘策略。
五、发现bug策略
六、心得体会
多线程显著提高了运行效率,牛。
测试数据不算卡人,感动。
上机实验给了模板,降低了难度,开心。

浙公网安备 33010602011771号