• BUAA面向对象第二单元作业总结


    三次作业总结主要分为以下几个部分的内容:

    • 多线程协同和控制
    • 基于度量的程序结构分析
    • 程序bug检验
    • 心得体会

    多线程协同和控制

      第一次作业为傻瓜式先来先服务电梯调度,而且不考虑捎带优化。所以设计非常简单,只需要满足相关的线程同步避免轮询即可。

      具体的设计为两个线程: (1) 电梯线程 (2)输入线程

        线程互斥:两个线程竞争的资源区为 一个公共的队列,所以对该队列的访问需要进行加锁,

        线程同步:当没有需求时,电梯线程等待;当输入添加到等待队列时,电梯线程被唤醒。

      第一次作业为多线程的基本应用,为保证扩展性,不增加优化部分。

      第二次作业为可稍带的先来先服务电梯调度。相比第一次只是增加了可稍带部分,所以只需要增加捎带算法即可。

      同样的捎带算法是电梯每层停靠时自主检测完成的,所以融入到第一次作业的互斥区访问即可。

      第三次作业增加到了三个电梯线程。

      设计之初,不考虑电梯间的协作优化,只考虑可达性问题,将需要换乘的部分分为两段,分别给不同电梯调度,通过计算可达矩阵完成电梯分配。

      每个需求到来时将其立即分配给某个电梯,则转化为第二次作业的部分。

      每个电梯拥有一个自己的需求等待队列,独立调度。完成某项需求第一部分时,判断是否需要换乘,如需换乘,添加到另一个电梯的队列中。

      所以这形成了一个哲学家就餐问题,再电梯换乘时,一个需求需要从一个队列删除再添加到另一个队列。

      为了破除这种锁嵌套获取的问题,采取了缓存flush策略,即,将所有需要换乘的需求缓存下来,释放掉删除需求队列的锁后, 再获取添加需求队列的锁,将所有需求添加进去。

      这样保证了任意线程再同一时刻只会有一把锁,不会产生死锁问题。

    基于度量的程序结构分析

    作业类图

      第一二次作业类图是第三次作业类图的真子集所以,下面只给出第三次作业的类图进行分析。

      从下图中可以看出,本单元类图结构十分清晰, transfor 类为计算转移矩阵的类,其被Input Model 和Elevator 调用。

      InputModel 和 ElevatorObj 是主要的两个线程,分别为输入调度类和电梯类,两者被主类所创建。

      InputModel 类中方法非常少,只有调度和输入,电梯把所有行为封装到自己内部,耦合性非常好。

      综上,本单元类的设计采取了简洁高效的策略,类之间分工明确,结构简单。

      

    UML 时序图

        下图为UML 时许图,三次作业均采用了两线程模式,输入模块同时也是调度器,电梯换乘可以被视作新需求的到达来。

        调度器将需求分配给某个电梯之后由电梯自行运转满足需求。

    第一次作业

       类的相关统计数据

      LOCM表示耦合程度,期望其值低;FANIN表示内聚程度,所以期望FANIN的值要高。

      

       方法度量 

      LOC表示代码行数,CC表示循环,PC表示方法的参数

      可以看出大部分方法行数较短,几个主要的方法行数比较长,这是比较符合常规的。

      

    第二次作业

      类的相关统计数据

      

         方法度量 

    第三次作业

      类的相关数据统计

     

      代码异味

      

      通过分析看出在out 函数中使用了大量的神仙数(没有明确标明意义的常数),这个在以后的作业中需要修正。

      以及比较复杂的条件和比较复杂的方法,这些都是需要进一步重构的方法。

      方法度量 

     

    程序bug检验

      对于程序中的bug检测,首先要立足于对多线程的深刻理解,在本三次作业中,虽然没有互测环节,但是我们还是尽量对自己的程序尽可能多的测试。

      Bug检验是一个由简单到复杂的过程:1.分析线程关系-> 2.线程是否公共资源互斥-> 3.线程是否可以进行同步 ->4.捎带效率和可达性检查

      脚本生成数据检查  

    1. 使用python脚本,随机生成需求,并再随机的时间按批次投入。
    2. 按照电梯运行规则进行检查输出结果 和运行时间

      检查出的错误主要有:

          (1)线程synchronize 区域粒度不够细,出现带锁睡觉

          (2)线程之间synchronize 嵌套,出现哲学家就餐问题

      在测试中出现的其他问题,对于最后结束添加一个NULL进入队列,所以需要对NULL的需求特判

      本地执行和采用命令行执行效果不一样,所以要经过命令行执行的检验。

      bug 主要处于线程访问公共资源区的位置Elevator 的Transfor 函数区,所以对公共资源访问和电梯同步要仔细设计检查。

      第一单元错误主要出现在顺序逻辑和某些输入WF情况下,对于多线程重点在于公共资源的互斥访问和线程的同步上。

     总结

        通过本单元的作业基本了解了面向对象多线程基础思想,进一步积累了一些重构的工程经验。

        线程安全上讲,尽可能地不要让一个线程同时获取两把锁,这样极有可能造成线程死锁。

        在线程同步方面,wait 和 notify 都是基于公共资源区的,这样从设计上可以避免死锁,同时也比较符合人的思维规范。

        在设计代码的时候首先分析出公共资源区,然后对公共资源区的访问代码范围尽可能缩小粒度,避免出现重叠现象。

        应该能够比较迅速的识别出经典的线程模式,如生产者消费者模型,哲学家就餐问题,发布订阅模式等,这些都有助于我们快速构建多线程代码。

  • 相关阅读:
    python操作Excel读写--使用xlrd
    python 使用pymssql连接sql server数据库
    python pdb调试
    sqlser生成guid与复制造数
    sqlser游标与for循环
    bat写循环
    Jenkins配置多任务
    git命令行与Jenkins
    Jenkins执行python脚本
    Windows环境Jenkins配置免密登录Linux
  • 原文地址:https://www.cnblogs.com/buaa-wsy-OO-2333/p/10744181.html
Copyright © 2020-2023  润新知