BUAAOO-第二单元总结

作业分析

同步块与锁

InputThread捕捉输入,将其加入waitQueue队列中

Dispatcher负责控制waitQueue,对waitQueue的操作需要经过Dispatcher

Elevator为电梯个体对象,其内包含一个requests用于表示目前位于电梯里的请求

其中,锁全部位于调度器中

例如

    public PersonRequest checkTopRequest() {
       synchronized (waitQueue) {
           int max = 0;
           PersonRequest request = null;
           for (PersonRequest r : waitQueue) {
               if (r.getFromFloor() > max) {
                   max = r.getFromFloor();
                   request = r;
              }
          }
           return request;
      }
  }

三次作业都为相同的设计,Dispatcher基本没有变动。

调度器设计与线程交互

外部可以放心与调度器进行交互,类似生产者消费者模型,调度器维护waitQueue,输入线程通过调度器向其中加入请求,电梯通过调度器查询和获取请求

第二、三次作业中加入了多个电梯与dispatcher交互

电梯策略:

Random:自由竞争,直接去找队列中第一个目标,接到请求后,优先处理电梯中的第一个请求,在运行过程中在每层判断是否可以接送乘客并且进行操作。

Morning:电梯位于1层,开始接人,2s后出发,一直送到电梯内请求列表的最高层后返回,依次循环

Night:直接前往队列中最高层接人,向下过程中继续接人,回到一层后依次循环。

UML

第一次作业

Main创建输入和电梯线程以及调度器,输入线程提供mode,requests,end等,调度器负责控制队列,elevator进行运行。

流程图:

第二次作业

相比第一次作业,输入线程负责创建新的Elevator

流程图

第三次作页

结构和第二次没有什么不同,在电梯类内部进行了ABC的区分,没有进行换乘的优化,仅仅是规定了各个电梯可人的层数后进行自由竞争。

流程图

分析自己程序的bug

在第一次作业没有互测bug。

第二次作业自测的bug主要集中在没有正确结束线程。

互测没有被找到bug,但是强测出现了一个超载的bug,原因在进行电梯可承载人数时加减号使用错误导致超载。

第三次作业自测阶段的bug主要在电梯由于型号不同,理论上结束标志不一,我在while循环结束的时候仅判断了input的信号,导致部分电梯提前结束,后来又因为没有正确结束导致while死循环CPU超时。

在互测中被hack一次,原因是我没有进行换乘优化,对方的数据点为集中的密集底层到高层数据,我的电梯只有C会去接人,导致超时。

分析自己发现别人程序bug所采用的策略

能力有限,这几次没有对他人的程序进行bug测试

心得体会

多线程的加入使得程序有了更多的不确定性,增加了测试的难度,但总而言之,只要做好线程的安全,如定义好线程安全类在进行操作,处理好线程的结束,不产生轮询,就可以避免多线程带来的bug。线程之间的交互在逻辑上就如同P6流水线的竞争一样,需要进行大量情况的考虑。在这几次作业中,我学会了多线程程序的正确处理。

 

posted @ 2021-04-25 22:33  acsoto  阅读(66)  评论(0)    收藏  举报