zoukankan      html  css  js  c++  java
  • OO第二次博客

    目录

    1.作业思路
    2.Bug回顾
    3.代码度量分析
    4.踩过的坑
    5.测试

    一.作业思路总结

    第一次作业(单部多线程傻瓜调度(FAFS)电梯模拟):

    ​ 多线程入门,作业相对简单。采用单例模式即可,即电梯们(其实就一部emm)和输入线程(主线程)共享调度器(请求队列集成在调度器里)。输入线程将读到的请求存入调度器,电梯从调度器获取请求,保证读写互斥即可。要注意线程结束的条件包括两点:

    1.输入线程读到null 2.电梯内的请求处理完毕。

    可以在调度器中设置一变量nullflag,当输入线程读到null时,将该变量设为true,电梯在向调度器交互获取nullflag状态,再在电梯内设一变量norequestflag来判断电梯内请求是否执行完,当两个变量都为true,结束电梯进程。!!!切勿在电梯内还有人的情况下就结束线程,电梯内的乘客该得多绝望~

    第二次作业(单部多线程可捎带调度(ALS)电梯的模拟):

    ​ 仍然采用单例模式,但是更改一下电梯,将电梯获取到的请求分为主请求和捎带请求,并且让电梯每移动一层就和调度器交互一次,在交互后更新电梯内部的请求队列,执行开关门、进出乘客等动作。电梯结束条件同一。不过值得一提的是相比于第一次作业,电梯系列第二次作业严格限制CPU时间(即线程占用CPU的时间)为10秒,因此在输入线程未读到null、调度器请求队列为空,电梯内的请求执行完毕时,将电梯线程阻塞起来(即wait()),待到输入新请求或者读到null时唤醒线程(notifyAll()),这样电梯线程在阻塞时就会让出CPU而不是处于忙等

    第三次作业(多部多线程智能(SS)调度电梯的模拟):

    ​ 仍然采用单例模式。保留第二次作业的电梯,主要更改调度器的请求分发策略,即多部电梯访问同一个调度器,由调度器来决定分发哪些请求给哪些电梯,每个电梯只需要执行获取到的请求即可,内部代码结构不需要过多改变。

    ​ 不过这一次作业的最大难点在于需要把请求进行拆分。在这次作业中,有三部电梯,楼层为-3到-1层和1-20层,共计23层,每部电梯只能到达其中的某些楼层,不同电梯可达的楼层是不一样的,那么很可能出现一条请求无法由一部电梯执行完的情况。此时需要将一条请求拆分成两条请求(former request和 later request)由不同电梯接力运送。需要保证later request在former request被电梯执行完后才能从调度器请求队列里边分发出去。所以在电梯们和调度器交互时,需在调度器里边存储各电梯内的请求队列,在决定是否分发later request时,先检查former request是否在调度器请求队列中,再遍历各电梯请求队列,看former request是否被执行完了。保证former request和later request执行的时序先后非常重要。

    ​ 还有就是电梯有了容量限制,在分发请求时要考虑电梯内当前人数以及其最大容量。

    二.Bug回顾

    第一次作业:

    ​ 非常简单,大家都没什么Bug,不说了

    第二次作业:

    ​ 电梯开关门的条件没判断好。当电梯当前楼层和主请求出发楼层不同时,电梯会移动到主请求出发楼层,此时电梯其实还没有将发出主请求的乘客装入电梯。此时若又途经主请求的目标楼层时,我这电梯会开门,让发出主请求的乘客下去,因此就出现了问题

    第三次作业:

    ​ 未发现Bug

    三.代码度量分析

    第一次作业

    第二次作业:

    第三次作业:

    结论:
    后两次作业代码量相对第一次偏大,调度器的get()方法(即请求的分发)以及电梯线程与调度器交互的interact()方法偏臃肿,未做到足够的简洁和拆分,有较大改进空间

    四.踩过的坑

    1.判断string对象相等时用equal方法和==的区别:

    ​ 首先equals方法是最稳妥的,比较的是两个字符串值是否相等

    ​ 对于==,比较的是两个string对象引用是否相等,情况分两种;

    String s1=new String("string");
    String s2=new String("string");
    System.out.println(s1==s2);//false
    
    String s3="string";
    String s4="string";
    System.out.println(s3==s4);//true
    
    System.out.println(s1==s3);//false
    

    ​ 第一项输出显然为false,因为s1和s2是两个new出来的不同对象,引用肯定不同

    ​ 第二项直观感觉上应该为true,那为什么第三个就是false呢?

    ​ 其实程序在运行时会创建字符串缓冲池,当使用到s3="string"这样的方式创建string对象时,会将new出来的“string”这个字符串对象加入缓冲池,以后在用于s4="string"时,s4直接赋为缓冲池里边相应字符串的应用,只有当写成s1=new String("string")形式时才会在堆空间另外创建一个新的"string"对象。因此才会出现上边的结果。

    2.初学多线程时遇到的问题:当主线程试图更改其他线程类的成员变量后,对方线程访问该成员变量的值其实没有发生改变。在第一次作业中我本来是想在电梯内设个nullflag,当主线程(输入线程)读到null时,更改电梯线程类的该成员变量,然后电梯定期访问该变量来实现通信,发现这方法不成功。目前猜测是主线程修改不了子线程栈空间的成员变量。

    五.测试

    第一次作业相对简单,没有过多测试。

    第二次、第三次主要是手动和半自动(用脚本定时投放数据来检测一些rtle的错误)的方式测试了一下输出结果的正确性,由于时间关系,对拍脚本Bug没调出来,也就没派上用场,不过我把代码上传到了gitlab,链接:https://gitlab.buaaoo.top/oo_2019_homeworks/oo_course_2019_17373174_homework_7/tree/master/对拍器

  • 相关阅读:
    命名是个技术活(转)
    我想知道的是这个月哪种商品销售量最高,比上个月怎么样?销量近几个月的走势是什么?有没有未达标的?有没有超额完成的?超额完成了多少?我可不关心这个月到底售出了多少件,几点售出的,谁买的(转)
    一个demo
    oracle 创建字段自增长——两种实现方式汇总(转)
    Ruby 一些经常使用的细节
    CMap与hash_map效率对照
    Unity 4.5.2 for Mac 下载+安装+破解
    Android中View绘制流程以及invalidate()等相关方法分析
    Android Studio 100 tips and tricks
    JavaScript-2.2 document.write 输出到页面的内容
  • 原文地址:https://www.cnblogs.com/notorious/p/10754083.html
Copyright © 2011-2022 走看看