2020年北航计算机学院面向对象第二单元总结

本文是2020年北航计算机学院面向对象编程的单元总结,重点讨论设计策略、架构可扩展性和程序结构度量。作者通过电梯调度的三次作业,学习并应用了生产者/消费者模式、Worker Thread模式,以及SRP、OCP等设计原则,并在实践中不断优化代码结构,解决线程安全问题。在第三次作业中,作者尝试了两种不同的架构设计,以提高调度效率和满足换乘需求。

这个单元中,我们主要通过电梯调度相关的程序学习了多线程以及一些常见的设计模式。

一、总结分析设计策略

第一次作业

本次作业,需要完成的任务为单部多线程可捎带电梯的模拟。 ——第一次作业指导书

第一次作业的难度并不大,主要是要初步掌握 Java 多线程程序的编写方法,尤其是保证多线程协作时的线程安全。为了达到这个目标,我们需要对相关方法或者成员变量进行加锁,我在这次作业中选择的是 synchronized 将 PassengerQueue 类中的 addPassenger 和 subPassenger 方法进行加锁。从而不管是输入线程向缓冲队列添加乘客请求还是电梯线程从缓冲队列获取请求,都不会产生数据冲突,尽可能保证线程安全。

我在这次作业中的设计模式,主要是参考生产者/消费者模式。采用了输入线程和电梯线程双线程的方法,输入线程主动添加乘客请求,电梯线程当电梯内为空即没有主请求的时候主动向缓冲队列获取请求。而缓冲队列相对而言只是承担了维护缓冲队列,也就是正在电梯外等待的乘客请求的容器。

在这次作业的过程中,相较之下,主要的困难在于初步掌握 Java 多线程的编写方法以及调试方法。

第二次作业

本次作业,需要完成的任务为多部多线程可捎带调度电梯的模拟。 ——第二次作业指导书

第二次作业相较于第一次作业增加了在程序开始时输入电梯数量的要求,同时对电梯中乘客数量也做了限制。随着电梯数量的增加,多部电梯协同调度算法也开始重要起来。

我在第二次作业的主要架构上,跟第一次作业没有大的变动,主要是在生产者/消费者模型的基础上,参考 Worker Thread 模式在细节上进行了一些修改。在第一次作业中,我的电梯进程是由 MainClass 直接产生并启动的,在这次作业中,由于电梯初始数量不确定,将这些任务都交给 MainClass 代码就不够有层次化了,也不符合主类尽可能简洁的要求。所以,我把这一个任务交给了 Channel,在 Channel 构建方法中根据电梯线程数量进行初始化,建立了 elevatorPool 对电梯进程进行统一管理,然后新建一个独立的方法来启动电梯。这样做,在一定程度上降低了类之间耦合性。

第三次作业

本次作业,需要完成的任务为多部多线程可捎带调度电梯的模拟。 ——第三次作业指导书

虽然在指导书的概述中与第二次作业没有任何差别,但是实际上相对于第二次作业还是有很大的不同的。主要是在前两次作业的基础上,增加了电梯停靠楼层以及运行过程中添加电梯的要求。后一个条件其实并没有带来很大的变化,主要是电梯停靠楼层的加入进而产生了一些换乘的需求。这些换乘需要进行一些宏观调度,不能单纯的将一个乘客请求调度至某个电梯,因为其有可能还要再次搭乘电梯。

第三次作业我用了两种架构来完成。

第一种架构

第一种架构是在我前两次作业的基础上迭代而来。主要是将 PersonRequest 包装成了 LiftRequest 类,在这个类中增加了对于是否需要换乘的判断,以及换乘的楼层、电梯等相关信息。将原来缓冲队列中的 PersonRequest 元素全部换成了 LiftRequest 元素,有助于换乘时进行判断。除此之外,大体上还是继承了之前的思路。

第二种架构

第二种架构是因为感觉原来的架构中的调度器担负的任务过多,不太符合面向对象的相关需求,对其进行拆分。

我建立了两层的 Scheduler 类,分为宏观调度和微观调度,分别对应 MasterScheduler 和 SlaveScheduler,均继承自 AbstractScheduler 接口。前者从 Inp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值