我采用的是生产者-消费者模型。有一个读入线程负责读入请求并发送给调度器。用一个调度器当输入请求来临时,由调度器分配给五个楼座的电梯线程去执行运送任务
输出线程:为保证TimableOutput。println()的线程安全,我创建了一个新的输出类,并对输出方法加了 synchronized锁。输出时将输出内容传给方法,保证输出线程安全
请求队列:新建了一个类PassengerList用来记录请求队列。使用synchronized方法保证进队,出队,查询人数等原子操作的独立性。该类用于输入类到调度器的请求传递,调度器分发给不同电梯的请求等。该请求队列类实用性,可扩展性强。
我是用的加强版的ALS。基准ALS在去往主请求的出发地时不会进行同方向捎带,我把这种情况设置为捎带,实测有一定的性能优化。调度器是通过的PassengerList类与电梯线程进行交互,使用生产者与消费者模型。调度器作为生产者向队列里加入请求,电梯线程作为消费者去执行请求。
在第一次作业的基础上做了增量开发,分别增加了如下类:
电梯线程的调度方法沿用第一次作业的。楼座(层)调度器采用平均分配的调度策略。通过PassengerList类接收Schedule类输入的请求,再通过该类分发给不同电梯线程。
本次作业迭代时不需要更改和实现新的同步块和锁
此次作业与上次不同关键在于乘客可换乘。由于乘客的路线可拆分成楼座(层)的基本路线。我通过新建乘客请求类PerRequest。在程序读入新的PersonRequest时计算最佳路线,编程PerRequest类喂给Input类。每次进入Input类以后将该请求按照当前基本路线运送。完成后更新目标基本路线后再次进入Input类,直到该请求到达最终目的地。其余调度器线程、电梯线程均不变。
本次作业迭代时不需要更改和实现新的调度器
本次作业迭代时不需要更改和实现新的同步块和锁
对于生产者-消费者模型中,消费者线程的结束判断要格外注意。该模块的错误和容易导致轮询,提前结束等bug。对于本次作业最终的迭代版本更像时流水线模型。对于这种层次化设计应找到一条主线,便于理清思路。本次任务可以抓住request在整个流水线中每一步要被分配到哪作为主线,去设计流水线的每一环。c