索命电梯
首先值得庆幸的一点是,这三次电梯作业我终于不需要重构了,基本上都是一套代码填填补补下来就OK。下图是我最后一次电梯的类图:
(最左侧没有截上的是java自带的Thread类。)
变量
下面简单的说一下我的三个类的变量含义。
Main类:
显而易见,就是跑线程用的。
Person类:
我也不知道当初在第一次电梯的时候怎么一个脑回路,就多写了一个Person类,而并没有采用jar包里的Request类,使得我第一次电梯多了一些没太大用处的重复定义和声明。不过在第三次电梯这个Person类就显得比较有用了。下面对Person类中的各个成员变量做解释:
(前两次:)
state:判断乘客的状态,0代表在电梯外,1代表在电梯内,2代表已经到达。
id、from、to:记录乘客的最基本信息。
(第三次:)
state:同前两次,0代表在电梯外,2代表在A电梯,3代表在B电梯,5代表在C电梯,-1代表已经到达。
upOrDown:判断乘客是上楼还是下楼
tmp:判断乘客乘坐过哪些电梯,初值为1,乘坐A电梯后tmp=tmp*2,B电梯tmp=tmp*3,C电梯tmp=tmp*5
waiting:判断是否已经有电梯正在前往接人。
Elev类:
num:现在电梯里的人数
max:最大载客量
id:A=2,B=3,C=5
ifnull:是否不再有乘客输入(文件输入停止)
nowTo:当前正在前往的楼层
set:乘客集合(static类型)
电梯运行机制
前两次:将最先出现的请求作为主请求,电梯先到set[0]的from,接上第一个人之后,通过getTo函数遍历ArrayList,得到要前往的to楼层,在其间经过的楼层一旦遇到有人想要上电梯(或下电梯)就开门,不论当前电梯与乘客目标楼层方向是否一致,因为在没有载客量限制的情况下,这种运行方法最省时间。
第三次:在第二次电梯上进行修改。
1.增加载客量限制。
2.增加电梯上下行机制,只有同向的乘客才能上电梯
3.增加乘客已经做过的电梯状态,避免一个乘客不停的上下同一个电梯
4.增加waiting变量,防止同一个人同时调用多个电梯,浪费资源
5.关于换乘:当一个乘客不能再通过乘坐一部电梯到达指定楼层时,就把他送到1层或15层(/狡猾),然后再修改乘客状态,此时显然一部电梯就能送到了。
电梯坑点
首先肯定就是static的使用了,我对set使用了static,但忘记了对所有修改set类型的函数加上static,导致我可怜的乘客们上了电梯,就被困在里面了。。。
接下来就是判断电梯停止的条件,在前两次作业中没有换乘,因此没有乘客请求就可以停止。而加入了换乘之后我的电梯停止逻辑就只能是所有乘客全部送到指定楼层。不然就出现了刚送到中转层就停止所有线程。。。
关于多线程的一些想法
这三次的多线程作业总体来说,如果不追求高性能,实际代码并不会很难。我的代码从第一次开始就一直沿用下来,并没有改变太多。而且老师和助教们一直推荐的调度器,我也并没有使用。但是由于多线程的随机性,许多边边角角的地方一个不留神,可能就会造成强测爆炸,因此我觉得在多线程中debug的能力真的是重中之重,而我的debug目前最有效的方式就是print,逐步添加print语句逼近bug,目前来看还是比较有效的。