面向对象课程第二单元总结

  本单元的整体多线程冒险体验对于我来说是要比第一单元好的……原因无他,我第一单元栽倒在输入处理和正则上的比例有点高,感觉除了设计上的丑陋之处,其他的全是输入处理上的问题= =……

  当然这并不代表本单元的冒险不紧张刺激,但至少省下输入处理的精力,我在代码结构的构造上面还是下了功夫的,整体构造感觉上要比第一单元更加合理一些(也许代码度量插件不这么想orz)。这其中也有老师教的合理的多线程设计模式的功劳,在已有的框架内,会把生产者消费者、仓库工人等等线程类所要完成的工作规定清楚,避免上帝类、废物类、奇怪线程类的出现。

  另外的收获就是对于多线程同步机制以及线程间通信的感悟。尤其是第二次作业为了照顾设计成丑八怪的调度算法,写了个二重生产者消费者机制,线程同步挂了很长一段时间才调好,具体还是留到底下作业分析之中细说。

第一次作业

  总体设计:使用生产者消费者模式,将输入作为生产者,将电梯作为消费者,将调度器作为共享对象。

  算法设计:由于规定是傻瓜调度,所以我并没有在算法优化上下功夫,只是进行了优化的思考,怕为了一口气吃个胖子把代码搞错。生产者没啥好说的,channel类也和课上介绍的差不多,消费者采用拿不到指令就wait(),拿到指令直接傻瓜调度跑完的方式,所有的输出一并写到了消费者类中。

  测试结果:强测以及互测均未出现问题。

第二次作业

  总体设计:使用一个非常杂技的双重生产者消费者模式, 生产者给仓库指令,消费者取走并自己维护一个队列(由于涉及到后续处理,必须要维护一个队列),然后把指令分为两部分,一部分作为可捎带指令直接喂给电梯线程类,另外一部分作为不可捎带指令存入一个叫做requestbuffer类做缓冲,再由电梯线程成批次取走。

  算法设计:整体实现上非常类似于look算法(只是类似,毕竟结果显示我算法还是写错了一些东西的),逐层进行指令的扫描,消费者队列为空时则去requestbuffer抓指令,抓一次把同方向的一批都抓走并从最远端开始运行电梯(向上就是最下一层,向下就是最上一层)。想的还是比较周到,但实际上构造起来过于杂技,缺点也比较明显。比如look算法没考虑队列所有指令,只按队列第一条确定下一步运行方向,在性能分上完全得不到保证;把电梯拉到最远端的初始化方法还很容易出错,比如说初始化的同时进入了一个由消费者线程喂过来的同向路上上车的指令,我就完全无法在本架构上处理(后来BUG中发现的,大改了一番才处理好)……类似的算法也在第三次得到了优化。

  测试结果:初始化的同时进入了一个由消费者线程喂过来的同向路上上车的指令无法处理导致了强测互测的一半错误,另一半是某个布尔变量初始化错了,导致按批去缓冲区抓来的指令有可能无法被我设计的初始化处理……actually,错误比较微妙,乍一测不好测出来,我当时对程序有些过于放心了,想的太少……

未完待续

猜你喜欢

转载自www.cnblogs.com/xsndzxc/p/10739622.html