面向对象第二单元总结
OO第二单元作业总结性博客
架构与设计
在三次作业中,我主要是对现实世界的电梯情况进行了模拟,将人上电梯的过程分了三个行为主体,分别是人、电梯、和调度器。
人
人不关心电梯怎么调度,人只管电梯开门时进出,另外在本次作业中人需要自己决定是否转乘以及在第几层转乘。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。电梯
电梯不关心怎样接人效率高、不关心有没有载人、不关心载的人在几层下。电梯需要知道的只是要往几层跑以及到一层时要不要开门。
调度器
调度器完成信息沟通和电梯调度工作。一是从人获得楼层信息然后综合计算后告知电梯运行方向以及停靠信息;二是从电梯获得到达信息并通知给人。
输入数据放在main中是主线程,另外每一个电梯是一个线程,以第三次作业为例,主线程不停的读入数据,根据读入的PersonRequest
对象构造Person
对象,添加到调度器维护的等待队列中并唤醒等待中线程,如果输入结束,将结束标志位endMark
置位,唤醒等待中线程然后退出。
public static void main(String[] args) {
TimableOutput.initStartTimestamp();
ElevatorInput elevatorInput = new ElevatorInput();
Scheduler.floorsInit();
Elevator elevator1 = new Elevator('A',400,false);
Elevator elevator2 = new Elevator('B',500,false);
Elevator elevator3 = new Elevator('C',600,true);
elevator1.start();
elevator2.start();
elevator3.start();
while (true) {
PersonRequest p = elevatorInput.nextPersonRequest();
if (p == null) {
Scheduler.setEndMark();
synchronized (Scheduler.lock) { Scheduler.lock.notifyAll(); }
return;
}
Scheduler.add(new Person(p));
synchronized (Scheduler.lock) { Scheduler.lock.notifyAll(); }
}
}
每个电梯线程建立后会向调度器要任务,如果要到就开始运行,每到一层向调度器询问是否需要停,如果停靠则执行停靠动作并通知调度器到达。具体流程见下图:
public class Elevator extends Thread {
private int nowFloor;
private int aimFloor;
private char label;
private int eleSpeed;
private boolean up;
public Elevator(char l,int s,boolean u) {
nowFloor = 1;
aimFloor = 1;
label = l;
eleSpeed = s;
up = u;
}
@Override
public void run() {
while (true) {
aimFloor = Scheduler.getTask(nowFloor,label,up);
if (aimFloor == 0) {
if (Scheduler.getEndMark()) {
synchronized (Scheduler.lock) {
Scheduler.lock.notifyAll();
}
return;
}
synchronized (Scheduler.lock) {
try {
Scheduler.lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
if (aimFloor > nowFloor) { up = true; }
else if (aimFloor < nowFloor) { up = false; }
move();
}
}
}
private void move() {
if (aimFloor > nowFloor) {
while (nowFloor < aimFloor) {
if (Scheduler.needToPause(nowFloor,label,up)) {
openDoor();
}
try { sleep(eleSpeed); }
catch (Exception e) { e.printStackTrace(); }
if (nowFloor == -1) { nowFloor = 1; }
else { nowFloor++; }
TimableOutput.println(String.format(
"ARRIVE-%d-%c",nowFloor,label));
}
} else if (aimFloor < nowFloor) {
while (nowFloor > aimFloor) {
if (Scheduler.needToPause(nowFloor,label,up)) {
openDoor();
}
try { sleep(eleSpeed); }
catch (Exception e) { e.printStackTrace(); }
if (nowFloor == 1) { nowFloor = -1; }
else { nowFloor--; }
TimableOutput.println(