欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

BUAAOO Unit2:电梯作业总结

最编程 2024-08-02 18:18:40
...

Unit2 电梯作业总结

0. 目录 

1. 作业分析

1.1 第5次作业——单部多线程电梯

1.1.1 需求分析

1.1.2 主要思路

1.1.3 主要的类及功能

1.1.4 调度器设计

调度器和线程的交互

1.1.5 同步块的设置和锁的选择

锁与同步块中处理语句直接的关系

1.2 第6次作业——多部同型号电梯的运行,可以动态增加电梯

1.2.1 需求分析

1.2.2 主要思路

1.2.3 新增类及功能

1.2.4 调度器设计

调度器和线程的交互

1.2.5 同步块的设置和锁的选择

锁与同步块中处理语句直接的关系

1.3 第7次作业——多部不同型号电梯的运行,可以动态增加电梯

1.3.1 需求分析

1.3.2 主要思路

1.3.3 新增类及功能

1.3.4 调度器设计

分配策略

调度策略

调度器和线程的交互

1.3.5 同步块的设置和锁的选择

锁与同步块中处理语句直接的关系

1.3.6 架构的可拓展性

UML类图

Sequence Diagram

功能设计和性能设计的Trade off

2. bug分析

第5次作业

第6次作业

第7次作业

3. hack策略

4. 心得体会

4.1 关于层次化设计:

4.2 关于线程安全

4.2.1 关于wait()和notifyAll()

4.2.2 关于Synchronize

 

1. 作业分析

1.1 第5次作业——单部多线程电梯

1.1.1 需求分析

只有1个电梯,有一定容量限制,乘客到达时间随到达模式的不同而异。到达模式分为Random、Morning、Night三种模式。

  • Morning:乘客到达间隔不超过2s,起始层都是底层。

  • Night:乘客在Night 指令到达时一次性全部到达,终点层都是底层。

  • Random:允许任何到达情况出现

1.1.2 主要思路

因为Morning模式乘客的起始层都是底层,所以我的想法是在读入的时候,如果是Morning模式就让电梯等待4s,再开始运人,这样可以避免最开始一次只运1个人的尴尬情况。对于其他Night模式当做Random模式来跑,即没有特殊的调度方法。

我使用了“消费者-生产者”模式,输入线程负责读入要乘坐电梯的乘客,然后将乘客放进缓冲区(WaitingRoom),然后电梯线程从WaitingRoom中读取乘客运人。

1.1.3 主要的类及功能

InputHandler:读入线程,从标准输入中读取数据,确定当前的到达模式以及读取即将乘坐电梯的乘客

WaitingRoom:用一个TreeMap来放置候乘的乘客们

Elevator:电梯线程,电梯线程负责“到达”、“楼层间运行”、“开门”、“关门”、“上人”、“下人”

RunningType:电梯的运行状态类型,分为:到达某一楼层ARRIVE、开门OPEN、关门CLOSE、楼层间运行MOVE、休息REST、结束END

ElevatorState:电梯的属性,属于电梯线程的一种性质,里面包括了电梯的运行方向、运行状态类型、电梯当前所处楼层、电梯最大容量、电梯当前容量、最高层、最低层、电梯所携带的乘客

Scheduler:根据当前电梯的ElevatorStateWaitingRoom的情况,决定Elevator的下一个运行状态。

1.1.4 调度器设计

在完成这一次作业时,我当时认为“调度器”就是实现电梯的调度算法的类。所以我的调度器就是Scheduler

我的调度器不是线程,而是决定电梯线程的运行状态,就如很多同学所说的“状态模式”,对我的调度器更像是一个状态模式的抽象,通过利用上学期计组学过的有限状态机根据这一时刻的电梯运行状态(ElevatorState)和WaitingRoom的情况来决定下一时刻电梯运行状态和下一个目标层。

对于电梯的下一个目标层我采用的调度方法是:LOOK算法

有限状态机的逻辑如下:

调度器和线程的交互

我的调度器只和电梯线程有交互。在Elevator中的run()方法中,对ELevatorState的电梯运行状态类型进行判断,使用了一个switch语句,根据REST、MOVE、OPEN、ARRIVE、OPEN、CLOSE、END来让电梯sleep相应的时间、并且进出乘客、改变楼层、改变方向、结束线程(即做出相应的动作)。

当做完相应的动作后,再调用Scheduler来确定下一个状态。

1.1.5 同步块的设置和锁的选择

这一次作业中,我对两个变量的读写取进行了加锁。

第一个当然是候乘表。我采用了“消费者-生