OO第二单元电梯线程系列总结作业

电梯系列第一次作业

功能描述:

傻瓜电梯无需考虑超载捎带

线程模式:

Producer-Consumer Pattern

思路:

第一次作业是一个傻瓜电梯,分别有一个生产者生成电梯指令(也就是Input接口),和一个消费者电梯(Process)运行指令和一个电梯调度器,

调度器为生产者和消费者共享,在生产和消费指令时,给队列上同一把锁,再通过wait();notify();

进行阻塞和唤醒调度器将生产者生产的命令放入电梯中,存放指令的队列使用的是Arrylist

 

线程安全:

由于ArrayList的成员方法都不是原子操作的,所以我通过集合Collections.synchronizedList将其转换为一个线程安全的类。

 

BUG分析:

本次作业较为简单,强测与互测均为出现bug

类图:

电梯系列第二次作业

功能描述:

一部电梯,实现捎带

线程模式:

Producer-Consumer Pattern

 

思路:

在第一次的基础上进行优化,增加电梯队列,一个是待执行队列(不能实现捎带),

一个是满足电梯运行方向条件,可以进行捎带的队列,调度器里面新增判断电梯的运行方向与指令的运行方向是否一致,

如果一致就加入

否则加入

调度器里还新增了一个电梯目前停靠楼层的原子变量(实现同步),通过判断可捎带的指令所在楼层与电梯目前停靠楼层是否一致来开关门捎带指令。

线程安全:

使用原子变量对部分代码上锁

将线程不安全的Arrylist容器换成线程安全的vector

阻塞和非阻塞的方法使用似乎并不影响线程安全

BUG分析:

(强测与互测均为出现bug)

类图:

电梯系列第三次作业

功能描述:

A,B,C三部电梯,需要实现捎带,最大上限载客人数不同,停靠楼层不同,运行时间不同

线程模式:

WorkerThread

 

思路:

先判断是否需要换乘电梯,将需要换乘电梯的指令拆分成两条指令,当第一部分的指令运行完之后,

再将第二部分的指令插入相应电梯中执行,不需要实现换乘的指令直接添加到对应电梯的队列中,电梯开关门时,

先出后进,在电梯上限容量搭载乘客,一定程度上节省了部分时间。

线程安全:

在插入换乘指令时,应该先将第一部分的指令放入相应电梯之后再开启子线程判断第一部分指令是否执行完毕(Id是否存在),

若执行完毕即可插入第二部分指令,否则就会出现线程安全,在拆分指令的时候程序就自动ctrl+d,读到的是空指令,

没有办法完成接下来的步骤。所以,应该把设计结构改一下,在第一条指令运行的时候才去启用一个新的线程判断指令是否执行完毕来运行第二条指令。

用原子变量当成锁来对部分代码上锁。

 

类图:

BUG分析:

Manage类中拆分指令判断出错,有一些楼层不在判断区域内,没有对自己的程序进行充分的测试,

导致没有输出,过了评测机中测后没有对自己的程序进行测试,导致强测挂了5个点。

 找BUG:

线程这种事情就是玄学,程序的错误就在那,但是交上去的数据不一定能复现这个错误,所以对于多线程,并没有去下载代码,

而是自己构造测试集对别人的代码进行检测。

测试策略差异:

第一单元是单线程程序,可以设置断点来debug,构造测试样例,根据输出来判断自己的程序是否有错
第二单元是多线程程序,只能依靠程序输出不断缩小代码范围,然后printf出觉得有问题的代码中的一些中间变量来找bug

猜你喜欢

转载自www.cnblogs.com/17373387lcy/p/10757254.html