OOUnit2

面向对象第二单元多线程总结

(1)设计策略

  • 第一次作业策略

    第一次作业单个ALS电梯,构建了三个线程类,调度器,电梯,输入管理。主线程中创建这些子线程,输入线程和调度器控制停止信号,电梯类和调度器通过生产者-消费者模型,通过synchronized块实现数据的共享。调度器和电梯通过创建的一个RequestQueue类进行人请求的管理,通过一个FloorQueue类细分每一层的进出请求。调度算法通过电梯和请求的方向来判断是否捎带。

  • 第二次作业策略

    第二次作业加入了多个电梯,根据输入控制电梯总数,每个电梯的自调度算法和第一次作业相同,另外加入总调度器的算法,把请求随机分配给每个电梯。

  • 第三次作业策略

    第三次作业新增了动态的电梯加入以及换乘,复杂度过高没能想到合适的解决策略。

(2)可扩展性

  • 第一次作业

    第一次作业满足每个类执行自己的职责,电梯和调度器分开,调度和输入管理分开。

  • 第二次作业

    第二次作业没有用到类的继承,重构了调度器满足分配给多个电梯。

  • 第三次作业

    没有实现

(3)基于度量分析

第三次作业没有实现,第二次作业出现暴力轮询ctle,给出第一次作业的度量分析:

  • 第一次作业

    • UML图

      OOUnit2_第1张图片

      调度器、电梯、输入管理之间的关系

    • 方法复杂度

      OOUnit2_第2张图片

    • 类复杂度
      OOUnit2_第3张图片

      调度器臃肿复杂度高,电梯只处理自身上行下行存储请求列表,和调度器之间不够平衡。

(4)分析自己程序的bug

  • 线程不安全,死锁的产生

    一开始我调度器和电梯还有输入管理之间职能划分不够细,耦合度较高,调度器在输入结束的时候会等待输入和电梯状态的变化,电梯在调度的时候会询问调度器有没有新请求的加入,最终会导致调度器和电梯互相等待进入死锁。解决方法为新增Tray类利用生产者-消费者模式,满足调度器和电梯之间的请求共享,由tray自行判断避免饥饿。同时输入管理类加入结束信号,调度器和电梯共享结束信号,当调度器收到结束信号并且传入所有请求给电梯时结束调度线程,当电梯收到结束信号并且电梯内没有未处理请求时结束电梯进程。

(5)发现别人程序bug所采用的策略

  • 构建边缘数据测试样例

(6)心得体会

  • 多线程的调试极其麻烦,不能设置断点,通过打印方式来寻找bug,通过研讨课上学习到的log打印进行调试。

你可能感兴趣的:(OOUnit2)