面对对象第二单元总结

文章讲述了作者在三次作业中逐步增加复杂性,实现多线程电梯系统的过程,涉及UML类图、协作图的设计,以及多线程编程中的线程安全、同步机制、死锁问题和解决方案。作者强调了并发编程的挑战和调试方法,并批评了理论与实践脱节的问题。
摘要由CSDN通过智能技术生成

第5次作业

目标

本次作业需要实现一个多线程电梯系统,共有6个电梯,11楼,每个乘客钦定乘坐哪个电梯,同时起点终点确定。

从标准输入中输入请求信息,请求信息按时间输入,程序进行接收和处理,模拟电梯运行,电梯操作有:开关门,移动,上下客,将必要的运行信息通过输出接口进行输出。

本次作业是多线程的第一次作业,不涉及乘客间与电梯间的信息交互,只需要处理好电梯乘客等待表中的可能的线程安全问题即可。

基本思路

我的主要类有三个:InputHandlerRequestListElevator。其中:

  • InputHandler处理输入,同时根据输入将乘客分配到合适的RequestList中。
  • RequestList存储某一电梯的乘客等待表
  • Elevator实现电梯,与其所绑定的RequestList进行交互,处理用户请求。

InputHandler和Elevator同时有对RequestList的访问,故在RequestList类中添加锁,所有对RequestList的操作都通过锁,锁通过sync语句块实现。

电梯调度使用LOOK算法,可以得到一个比较好的效果。

UML类图

在这里插入图片描述

UML协作图

在这里插入图片描述

出现的bug

强侧通过,互测被hack了一次,原因是锁没加好,Strategy类中对RequestList的访问不安全。

第6次作业

相比于第五次作业,第6次作业增加了电梯的reset操作以及新增调度器的需求。

难点分析

在这次作业中,可以发现线程的访问关系形成了一个环,这就导致了很多bug的产生。

基本思路

由于访问关系成环,为了防止死锁,考虑生产者消费者模型,新增PersonBuffer类和Distributer类,分别用来作为交互中间件与分配器。

  • InputHandler向PersonBuffer中添加人,同时Elevator在reset开始时也向PersonBuffer中添加人,为生产者
  • Distributer从PersonBuffer中加人,为消费者

在这种设计下,可以较好的分割开类的功能,以减少bug的产生。

对于分配策略的选择,我使用影子电梯实现,具体方法是通过继承Elevator类并替换其中与时间计算相关部分来达到简易扩展,每次调度请求产生时,分配器根据每个电梯的状态复制影子电梯,并根据结束时间将请求放入结束时间较少的电梯中,以达到最大优化效果。

在这次作业中我选择使用ReentrantLock来实现锁的机制,相较于sync语句块其具有较强灵活性。

UML类图

在这里插入图片描述

UML协作图

在这里插入图片描述

出现的bug

强测通过,互测被hack一次,锁没加全,在Elevator类中执行Action时的状态和获得Action的状态不同,进而导致死锁bug产生。

第7次作业

相比于第6次作业,第7次作业新增了双轿厢电梯。

难点分析

  • 双轿厢电梯不能同时停靠换乘楼层,这给电梯调度产生了额外的复杂度
  • 双轿厢电梯在使用影子电梯时不是很好实现,容易产生bug

基本思路

对于停靠楼层的限制,我新增了一个锁来表示楼层占用情况,电梯想要进入换乘楼层则必须获得该锁,否则不能进入换乘楼层,这样就可以实现双轿厢的两个轿厢不碰撞。

由于影子电梯实现过程中带来了很高的复杂度,很容易产生bug,故我在这次作业中没有实现影子电梯的调度策略,而是通过电梯的参数,加权求和来近似求出电梯结束时间。通过调整权重,可以在时间、电量等多个性能指标中实现一定的平衡。

UML类图

在这里插入图片描述

UML时序图

在这里插入图片描述

最终代码量

在这里插入图片描述

bug分析

这次作业中我通过了强测与互测,没有bug产生,由于没有实现影子电梯,可能产生的bug少了很多,这对bug的查找与分析带来了便利。

总结

这个单元不变的就是要一直处理多线程程序的特性与bug,包括进程通信方式,如何交互等,还有基本的架构也是没有改变的,都是输入,分配,电梯运行,调度策略这4个部分,其中的细节变化还是比较大的,从钦定电梯到自由分配再到多轿厢电梯,变化虽然大但又很大一部分是在做增量,想清楚后写起来还是不算非常困难的。

这个单元使用到了多线程的相关知识,多线程程序是非常容易出错的,但是其复现又十分困难,我在debug时主要使用输出中间过程的方法,从中间过程去反推bug出现的位置,虽然该过程比较耗费时间,但是的确是少数有效的debug方式。

感觉多线程编程想要避免bug还是很困难的,从串行程序的线性运行变成并行程序的多个线程并行,是相当于升高了好几个维度,需要考虑的东西多了很多,导致线程安全是困难的,这对代码能力提出了很高的要求。

在这个单元中评测机帮助我发现了很多bug,但是对于并发程序,再多的测试也不能保证其正确性,指不定哪里执行顺序一变就又产生了新的bug,防不胜防。

besides,感觉理论课和作业严重脱节,理论课给我的感觉就是讲的过于细致,大讲各种设计模式、架构模式,讲java中多线程的具体细节,然后就给出一堆多线程的问题,令人迷惑,感觉不如把多线程的基本思路,多线程错误类别(如原子性违反、顺序违反)这些东西讲讲清楚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值