这一单元作业是围绕电梯调度进行展开,并引进了多线程的概念。与第一次作业比较类似,作业难度也是逐渐推进,从最开始的单部电梯先来先服务(傻瓜式调度),到之后的单部电梯可稍带调度,到最后的多部电梯分楼层调度。下面分别说明并分析一下三次作业的设计结构。

第一次作业

作业概述:程序的输入流会不定时随机投放若干用户请求,用户的请求包括出发楼层和目标楼层,电梯没有容量限额,在规定时间上内完成所有请求。

这次作业的意图是让大家对线程有一个初步的认识(因为用户请求不定时投放,电梯强制在线必须要用线程才能搞定),共享对象的加锁保护以及线程之间的同步控制。单论本次作业的难度还是很低的,我大概用了三四个小时就完成了本次作业。

设计策略

由于第一次作业只有正确性要求,没有性能分,所以我也就没费工夫想如何优化调度hhh,就直接写了个先来先服务的模型。尽管电梯很愚蠢,看着有人经过也不捎带一下。。。但是在正确性上有十分充足的保证。

实际上,第一次作业得电梯调度就是最经典得生产者消费者模型,整个代码也就分为了三个部分,两个线程。主线程也就是第一部分用来接收用户请求,也就是生产者,另一部分是共享对象用来存储请求队列,最后一部分是电梯线程用来从请求队列中获取请求,也就是消费者。

代码分析

设计图

各个类得作用请见设计策略。也没什么可具体分析的了。

度量分析

可以看出这次设计的层次还算不错,各个指标都没有特别高的。当然这是因为这次作业比较简单。

Bug分析

分析自己程序的bug: 这次作业没有bug。
分析他人程序的bug: 高工这块没有互测部分,但是也和同学私下互相讨论过,测试方法就是写几个测试样例看看结果是否正确,以及看看代码内部是否有明显的逻辑漏洞。均为发现错误。

第二次作业

作业概述:这次作业和第一次作业基本一样,也是一部电梯,同时没有人数限制。唯一的区别就是要完成捎带调度。当然说是增加了调度算法,但是实现起来还是十分容易的。只需要每次到达一层楼的时候看一眼该楼层是否存在相同运行方向的等待的人。

设计策略

基本和第一次作业一样,同样都是两个线程,分别是主线程读取用户请求,子线程运行电梯。共享队列实际上是内置在电梯中的,但是为了方便理解,我还是单独写了一个共享队列的类,但是并没有做成线程,只是经了一下手立马就发给了电梯的内置队列(自己骗自己hhh)

代码分析

设计图

度量分析

Bug分析

分析自己程序的bug:似乎还是没有bug。。。这次虽然还是没有bug,但是因为有了性能分,所以并不是满分。我也只是实现了指导书中推荐的捎带算法,没有考虑其他更好的优化方法。实在是打不过优化大佬们。。。
分析他人程序的bug:在和其他小伙伴交流的时候还是没有发现什么bug,有的同学是把所有请求都添加到电梯中,也就是不管这个人是向上走还是向下走,你先进来,先和我绕一圈回头我再送你去你的楼层。虽然很不符合实际,但是似乎比常规的捎带方法最终的时间还要短。。也是有点意思。

第三次作业

作业概述:这次作业有了很大的升级,分为了三个电梯,每个电梯可以停留的楼层还不一样,有的人还必须要换乘才能到达指定的楼层。各个电梯的速度也不一样。

设计策略

这次的设计结构不同于上述两次作业,要复杂很多。由于这个有三个电梯也就是有多个消费者,所以并不能像之前那样把共享对象写在电梯里面,而是要有一个调度器对所用请求指定电梯后,在电梯内部再进行二次调度,也就是可稍带调度。所以总体上是有五个线程,一个主线程接收请求,一个子线程作为主控用来处理请求队列的分发,剩下三个是电梯线程,用来处理每个电梯的调度以及电梯的运行。但实际上由于这里有的请求非常的麻烦,需要不同电梯协同工作才能完成,比如说请求要从20->3楼,而只有A电梯能停留20楼,只有C电梯能停留3楼。所以这种情况我的处理办法是先让A电梯停留在一个AC都能停留的楼层,比如说5楼,然后这时把请求发到5楼同时修改成一个新的请求为5->3楼,这样再把这个新的请求发送给主控的共享队列。也就是说除了Main线程是生产者以外,电梯内部也可以生产新的请求。至于是如何调度的,我的调度器十分简单,就是先判断是否有直达电梯,并将请求发给最近的直达电梯。如果没有可用的直达电梯(两种情况,直达满了,或者就是需要中转的)就给一个最近的电梯。电梯到每一层的运输规则都是写死的,比如如果能直达就直达就ok了,但像A电梯不能到3楼,所有通过A想去3楼的就都会送到5楼。显而易见,我这种方式绝对不优,甚至有时候很愚蠢。

代码分析

设计图

度量分析

可见Request类的sendRequest()函数的度量值很高,这是因为里面进行了非常对的if判断,来分类到底要给哪个电梯。

Bug分析

分析自己程序的bug:依旧没有bug。
分析他人程序的bug:我看的大多数小伙伴的代码bug主要集中在程序结束判断上。当然不同人写法不一样,但大体来讲不能简单通过Main线程的输入结束来判断是否要关闭主控线程,必须要等所有的电梯都结束了同时没有输入了才能关闭。

总结

先从课程作业体验上讲一下,总体感觉这一单元的体验要比上一单元好一些,代码写得也顺利很多,最多用一天就都能写完(难道是我进步了???)。
在说说多线程编程的体会吧,总的来讲前两次作业不需要太多的思考,简单加个同步锁就ok了。但是在第三次就了一些更深的感受,首先多线程debug就很不同,单步调试基本没啥用,print会更直接。其次就是加锁的艺术,有的时候全部加上锁肯定没问题,但是性能会下降很多,但是如果减少锁的范围可能又会出现不同步带来的bug,所以需要好好权衡和设计这块。

最后感谢老师和助教的帮助和指导!

OO第二单元总结的更多相关文章

  1. oo第二单元作业总结

    oo第二单元博客总结 在第一单元求导结束后,迎来了第二单元的多线程电梯的问题,在本单元前两次作业中个人主要应用两个线程,采用“生产者-消费者”模式和共享数据变量的方式解决问题.在第三次作业中加入多个电 ...

  2. OO第二单元优化博客

    OO第二单元优化博客 第五次作业没有性能分,但是,我在这一单元的宗旨就是写一个日常生活中 最常见的那种电梯,所以第五次我没有写傻瓜电梯,而是直接写了个\(look\),和第六次基本相同. 总计一下lo ...

  3. 【OO学习】OO第二单元作业总结

    OO第二单元作业总结 在第二单元作业中,我们通过多线程的手段实现了电梯调度,前两次作业是单电梯调度,第三次作业是多电梯调度.这个单元中的性能分要求是完成所有请求的时间最短,因此在简单实现电梯调度的基础 ...

  4. OO第二单元小结

    OO第二单元小结 一.三次作业代码分析. 1.第一次作业 第一次作业是单部电梯的傻瓜调度,由于其过分傻瓜,所以第一次作业我只有两个类,一个main,一个电梯,main类负责不断从输入流中读取命令,如果 ...

  5. OO第二单元多线程电梯总结

    OO第二单元多线程电梯总结 第一次作业 设计思路 Input为输入线程,负责不断读取请求并将读到的请求放入调度器中. Dispatcher为调度器,是Input线程和Elevator线程的共享对象,采 ...

  6. 电梯也能无为而治——oo第二单元作业总结

    oo第二单元作业总结 一.设计策略与质量分析 第一次作业 设计策略 在第一次作业之前,我首先确定了生产者--消费者模式的大体架构,即由输入线程(可与主线程合并)充当生产者,电梯线程充当消费者,二者不直 ...

  7. 2020北航OO第二单元总结

    2020北航OO第二单元总结 前言 本单元考察基于多线程的电梯调度问题,成功让我从一个多线程小白到了基本掌握了使用锁来控制线程安全的能力,收获颇多(充分体验了迷茫地de一个又一个死锁bug的痛苦). ...

  8. OO第二单元——多线程(电梯)

    OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...

  9. OO第二单元作业总结【自我反思与审视】

    第二单元作业的完成史,就是一部心酸的血泪史…… 多线程的出现为我(们)打开一片广阔的天地,我也在这方天地摸爬滚打,不断成长!如果说第一单元之前还对Java语法有所了解的话,那么这单元学习多线程则完全是 ...

  10. OO第二单元(电梯)单元总结

    OO第一单元(求导)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉理解和掌握多线程的思想和方法.这个单元以电梯为主题,从一开始的最简单的单部傻瓜调度(FAFS)电梯到最后的多部 ...

随机推荐

  1. JAVA使用POI获取Excel的列数与行数

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能. 下面这篇文章给大家介 ...

  2. PHP Array 简介

    PHP Array 简介 数组函数允许您访问和操作数组. 支持单维和多维数组. 安装 数组函数属于 PHP 核心部分.无需安装即可使用这些函数. PHP 5 Array 函数 函数 描述 array( ...

  3. 【开发记录】如何在B/S项目中使用中国天气的实时天气功能

    好久没有更新我的博客了,正好手头有一个比较合适的项目经验可以分享出来,就是这个如何使用中国天气的天气预报功能,也正好做个项目经验记录. 功能需求 这个功能需求比较简单,就是想在网页端显示实时天气数据. ...

  4. .NET、C#和ASP.NET三者之间的区别

    一.什么是.NET?.NET是微软公司下的一个开发平台,.NET核心就是.NET Framwork(.NET框架)是.NET程序开发和运行的环境,在这个平台下可以用不同的语言进行开发,因为.NET是跨 ...

  5. Flutter 异常处理之图片篇

    背景 说到异常处理,你可能直接会认为不就是 try-catch 的事情,至于写一篇文章单独来说明吗? 如果你是这么想的,那么本篇说不定会给你惊喜哦~ 而且本篇聚焦在图片的异常处理. 场景 学以致用,有 ...

  6. JS INPUT输入的时候全角自动转为半角

    function CtoH(obj){var str=obj.value;var result="";for (var i = 0; i < str.length; i++) ...

  7. Java中char,short,int,long占几个字节和多少位

    1.字节:byte:用来计量存储容量的一种计量单位:位:bit 2.一个字节等于8位  1byte = 8bit char占用的是2个字节 16位,所以一个char类型的可以存储一个汉字. 整型: b ...

  8. 开发vue但不使用vue-cli和webpack相关注意事项

    1.绑定vue组件使用new Vue() 2.new Vue()需要在dom结构生成之后才有效(毕竟有需要el) 3.Vue.component注册全局组件在vue容器组件挂载之前才有效 4.当然,可 ...

  9. .NET Core 性能分析: xUnit.Performance 简介

    xunit-performance 是xUnit的一个扩展, 使用它可以对.NET Core项目进行性能测试. 官网:https://github.com/Microsoft/xunit-perfor ...

  10. Vue.js-06:第六章 - 按键修饰符的使用

    一.前言  上周末的时候,准备试试将 ASP.NET Core 的项目部署到 CentOS 服务器上,结果在一个接一个坑里面跳,最后 Supervisor 守护程序还是有问题,于是,采用重装系统大招, ...