2021面向对象第二单元总结

一、同步块的设置和锁的选择

由于三次作业电梯和调度器的功能基本相同,只是调度的算法有所变化,所以我三次作业的同步块和锁的设计基本类似。都是对与调度器的锁进行获取。当输入线程获得调度器的锁且输入队列有请求时就会将请求送入调度器中,此时调度器由于没有获得锁,就避免了调度器和输入线程同时对调度器等待请求队列处理,保证了线程安全,而调度器线程获得自己的锁时就会处理请求,避免输入线程和电梯线程的干扰,当电梯线程获得调度器的锁时,就会运行,避免调度器对电梯等待队列干扰。

二、调度器设计

我的三次电梯作业的总体设计是输入线程只负责从控制台读取输入并将请求交给调度器,调度器线程负责分析请求类型,如果是电梯增加请求就增加电梯,如果是人请求就按照一定的算法分配给电梯,电梯线程负责处理人请求,并输出相应的输出信息。

第一次作业

由于第一次作业只有一部电梯,且电梯功能也比较单一,调度器的功能和输入线程功能差不多,但为了程序的可扩展性我还是设计了调度器,此时调度器只用来将输入线程送来的请求送给电梯。

第二次作业

由于这次作业增加了几部电梯,同时增加了电梯增加请求,所以需要调度器来处理电梯增加请求。由于这次有多部电梯,就会存在人请求分配的问题。因为电梯之间没有区别,为了避免一部电梯过于繁忙,我选择将人请求尽量平均分配给几部电梯,使得各个电梯之间尽可能的相同繁忙。

第三次作业

这次作业在第二次作业的基础上增加了电梯的类型,不同的电梯能到达的楼层不同,但存在一部电梯可以到达所有楼层,电梯能到达的楼层越多移动的时间就越长,为了缩减运行时间,就必须采用更合理的分配方式,我选择能够让B或C直达的请求就由B、C处理,B、C不能直达但可以换乘的就换乘,剩下的交给A类电梯,但为了避免出现所有请求都由B、C处理,我设置当B、C的等待队列大于A等待队列的两倍时就分配给A。

三、第三次作业架构与可扩展性

 

 本次电梯作业中有不同种类的电梯,可以采用工厂模式来创建电梯,同时,电梯和调度器,输入线程的关系也可以采用生产者消费者模式来增强扩展性。

四、分析自己程序的bug

这次作业逻辑功能部分比较简单没有出什么问题,主要问题都出现在线程安全问题上,在第五次作业中测里有一个测试点没有过,后面强测也出现了一个点没有过,主要是因为当电梯在某层有人出去后,此时调度器又送过来一个同层请求,这时电梯会将它加入等待队列再将它加入运行队列,但由于多线程的运行次序不可控,可能会出现电梯判断此时应该将它加入等待队列再将它加入运行队列并认为这样做了,但此时实际等待队列为空,电梯先判断认为没有人了,就关门了,这样就不会处理这个请求,由于有人没有送到目的地,程序就会一直运行,直到TLE。第六次作业中测和强测互测都没有问题,第七次作业强测有两个点没过,是因为第七次作业存在换乘,可能会有C电梯将请求送给调度器,但此时调度器已空,且输入关闭,B电梯等待队列运行队列全为空,B电梯认为程序已结束就退出,但调度器此时收到请求后分配给B,由于B已经退出运行,所以这个请求就无法处理,就会出现TLE。

五、分析自己发现别人 Bug 所采用的方法策略

本单元作业的Bug主要存在于线程安全。可以通过分析别人采取的同步方式和锁,来判断可能会存在什么类型的线程安全问题。本单元测试策略与上一单元有很大的不同,因为本单元的答案不像上一单元是一对一对应,不同的人采取不同的策略会有不同的运行方式和时间,构造测试用例比上一单元要复杂不少。

六、心得体会

本单元作业通过模拟电梯运行的方式实现多线程的程序的设计,这是我第一次使用多线程编程,在线程安全上有许多考虑不周的地方,同时本单元的作业完成情况比上一单元要好很多,希望下一单元继续努力,继续进步。加油!!!

posted @ 2021-04-27 21:38  白屋出宫卿  阅读(60)  评论(0)    收藏  举报