BUAA OO UNIT2单元总结

黄弘烨-22371430 黄弘烨-22371430 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

同步块的选择

由于我架构的设计,整个代码中存在三种队列:waitingQueue、RequestQueue和LeaveQueue,这三个队列就是整个架构中最核心的“临界资源”。

具体体现为,waitingQueue链接了Input和Scheduler,而RequestQueue链接了Scheduler和Elevator,每个队列都处在两层结构之间的“临界区域”。

这种架构最优秀的地方,在于同步块会很集中,也就不容易遗漏。

每次访问各种Queue时,仅需要对Queue上锁,并且为队列中的每个方法上锁,即可确保各种类之间不会出现数据竞争。

也正是这种清晰的代码结构,给我的代码带来了很强的生命力,极其容易阅读、理解和维护。

调度器的设计

调度器通过waitingQueue链接着Input,通过RequestQueue链接着Elevator,是整个代码的枢纽所在。正如前文所述,他与其他类的交互,正是通过waitingQueue、RequestQueue这两个线程安全的类实现的,也就不存在任何的线程安全问题。

public class Schedule extends Thread {
    private WaitingQueue waitingQueue;
    private ArrayList<RequestQueue> processingQueues;
    private ArrayList<Elevator> elevators;

Input中的数据会通过waitingQueue的addRequest方法移到调度器中,再通过各种线程安全方法通过队列转移到Elevator,实现了工程流水线的封装。

调度策略:整体的调度策略是以时间为主要核心的。通过影子电梯的模拟方式,提前计算出每个电梯需要花费的时间,再对每个请求进行分配。

纵观整个单元,调度器是最稳定的一个类之一,仅次于输入流。在第一次迭代时,仅仅只是更改了调度策略,从固定调度改为计算时间后分配。修改的代码量仅有数行(计算过程被封装在电梯的函数中);而第二次迭代则完全没有任何变化。

电梯的不相碰

  1. 最主要的一点在于对换乘楼层的互斥访问,通过设立一个mutex信号量,保证每次仅有一个电梯访问换乘区,另一个电梯必须等待信号量释放。

    public synchronized void moveToNextFloor() {
         int nextFloor = curFloor + direction;
         int oldFloor = curFloor;
         if (type != 0 && nextFloor == trans) {
             if (isTrans[id] == 0) {
                 isTrans[id] = 1;
             } else {
                 while (isTrans[id] == 1) {
                     try {
                         this.wait();
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
                 }
             }
         }
    
         this.curFloor = nextFloor;
         sleepForATime((long)(moveTime * 1000));
         output("ARRIVE", 0);
    
         if (type != 0 && oldFloor == trans) {
             if (isTrans[id] == 1) {
                 isTrans[id] = 0;
                 synchronized (otherElevator) {
                     otherElevator.notify();
                 }
             }
         }
     }
    
  2. 其次保证不相碰的一点就是让电梯及时让位。通过让电梯在空闲时移出临界区,来为移动的电梯腾开换乘区的位置

    if (inQueue.isEmpty()) {
                 synchronized (processingQueue) {
                     if (processingQueue.isEmpty() && type != 0 && curFloor == trans) {
                         setDirection();
                         moveToNextFloor();
                     } 
    

bug相关

最明显的bug莫过于与程序结束相关的bug。在第一次作业中,我们注意到waitingQueue仅仅来源于输入流,当输入结束时,会引起等待队列--处理中队列一系列的结束,最终让程序结束。

但是这跟第二次作业时不同的。在第二次作业中,waitingQueue还有一种来源——reset释放后的乘客。如果不加以处理,就会导致程序结束时还有人没有送完的情况。

而第三次作业又多了一条路径,也就是换乘的乘客。

这三条路径需要对应三种不同的end信号。实现这个end信号的过程需要一点技巧,也算是这个单元很有趣的bug修复过程。

debug相关

这个单元的debug极其折磨。由于无法使用断点等办法,只能使用手动输出的方式获取程序运行的路径;但是程序的运行又极其的慢,修改一次输出信息,就要重新跑数十秒。目前只有通过一些黑科技来加快“时间流速”,其他的好办法一概不知,希望uu来点建议。

线程安全相关

线程一旦出现问题,不管是debug的成本,还是发现问题后修复的成本都极其高(而且对心态打击极大),所以每次写代码时必须谨慎(不然一旦出现线程安全问题就容易跟我一样开摆)

而这次我的作业极其符合层次化设计,四层大类+三条线程安全连接的数据结构,让我的代码极其清晰而易于维护,我将学习这次的经验,并且将这次做的好的地方继续发扬下去。

...全文

相关推荐

29Linux基础命令详解——用户管理.docx

29Linux基础命令详解——用户管理

云计算练习生

科技服务机构如何通过数据分析增强服务竞争力?.docx

科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

vue+springboot基于 Java 的南昌实利广告公司的员工管理系统的设计与实现_oj680rl3毕业设计源码数据库.zip

vue+springboot基于 Java 的南昌实利广告公司的员工管理系统的设计与实现_oj680rl3毕业设计源码数据库.zip

源码论文专家

车辆缺陷分割数据集4000张json格式.zip

数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):4000 标注数量(json文件个数):4000 标注类别数:1 标注类别名称:["defect"] 每个类别标注的框数: defect count = 8740 总框数:8740 使用标注工具:labelme=5.5.0 所在仓库:firc-dataset 图片分辨率:640x640 标注规则:对类别进行画多边形框polygon 重要说明:可以将数据集用labelme打开编辑,json数据集需自己转成mask或者yolo格式或者coco格式作语义分割或者实例分割 特别声明:本数据集不对训练的模型或者权重文件精度作任何保证

不会仰游的河马君

高校如何利用技术转移服务转化科研成果并提升影响力?.docx

高校如何利用技术转移服务转化科研成果并提升影响力?

BIZKEEN
评论
收藏 已收藏
分享
返回顶部