OO第二單元--多線程電梯

1、設計策略

(1)單電梯:

  a、線程分工:

    elevator、request兩個線程。設計模式

      elevator線程主要負責乘客的接送和進出。安全

      request線程是接收乘客信息。多線程

    control是緩衝器,用來保存elevator和request兩個線程共享的乘客隊列。架構

  b、調度策略:

    以電梯當前樓層和運行狀態爲基準,若是電梯是上行的,而且高於當前樓層還有乘客要進出就上行,不然判斷是否低於該樓層有需求,若是有就下行。反之亦然,如果沒有需求,則令電梯中止。對於乘客的調度則是到了規定樓層,能出則出,能進則進。函數

(2)多電梯1.0:

  a、線程分工:

    elevator類的五個電梯線程以及request線程。學習

    elevator線程主要負責乘客的接送和進出。測試

    request線程是接收乘客信息。spa

    control是緩衝器,用來保存elevator和request兩個線程共享的乘客隊列。線程

 

  b、調度策略:

    基於第一次做業的單電梯,將request中得到的乘客,平分到每一個電梯中。設計

(3)多電梯2.0:

  a、線程分工:

    elevator類的若干個線程以及request線程。

    elevator線程主要負責乘客的接送和進出。

    request線程是接收乘客信息。

    control是緩衝器,用來保存elevator和request兩個線程共享的乘客隊列,以及保存電梯類的個數。

  b、調度策略:

    擴展PersonRequest類的功能,便於進行換乘操做。根據ABC不一樣的電梯停靠樓層對接收的乘客進行分類。可以直達的儘可能直達,如果出現都能直達的狀況根據ABC的優先級進行分類。如果不能直達的,則根據出發樓層ABC進行分類,換乘樓層集中在固定樓層一、五、15,便於進行操做,減小開關門的時間損失。對於同類別的不一樣電梯的乘客調度同第二次做業,對於電梯的運行同第一次做業。

2、第三次做業的可擴展性(SOLID原則)

(1)SRP(單一職責)原則

   request類主要進行生產者線程,elevator進行電梯的主要功能,control進行乘客信息的調度以及保存。三類的功能都不相同,符合單一職責的原則。在control中雖然有不少的方法,可是執行的目的都是十分簡單,仍是符單一職責原則。

(2)OCP(開放封閉)原則

   由於沒有在寫做業時,沒有考慮代碼的可擴展性,不少方法在第三次多電梯的實現中,進行了些許的調整,若是該電梯還要進行一些擴展操做,我想對於這些方法仍是應該要進行調整。所以我以爲第三次做業的OCP原則仍是不是很好。

(3)LSP(替換)原則

   第三次做業中我單獨寫了三個電梯類,沒有歸類到一個父類裏面,由於在建立類,以及執行過程當中都是用的電梯序號,因此沒有這方面的問題。

(4)ISP(接口隔離)原則

    對於不一樣電梯,經過電梯索引來對電梯進行操做,在後續的幾回拓展都獲得一個很好的實現,因此相對來講接口隔離實現得比較好。可是對於電梯沒有經過屬性規範,而是獨立的創建了三個電梯類,我以爲這一方面的接口原則就處理得不是很好。

(5)DIP(依賴倒置)原則

   control緩衝區元素的創建依賴request的運行,elevator的執行和創建依賴control,沒有出現循環依賴的狀況,仍是很好的知足了依賴倒置的狀況。

3、度量分析

 

(1)第一次做業:

    UML

 

 

 

    複雜度分析

 

    a、dependency

 

 

 

 

    b、 complexity

 

    總結

 

     複雜度較好,可是對於control的setUpFloor方法的複雜度就比較高,這跟個人調度策略有着很大的關係,四次用到循環,結果做爲條件的一種嵌套,都增長了複雜度,而這些在後續幾回做業都有體現。

 

(2)第二次做業:

    UML

    複雜度分析

    a、dependency

    b、 complexity

 

 

    總結

     這一次做業的的獨立性相對比較好,可是複雜度分析有不少的方法爆紅,特別是setUpFloor的方法,我想應該是在該方法有四個循環,致使該方法的複雜度很高,並且得出的結果又會用來下一次的判斷條件,因此有一個嵌套的複雜度,可是關於該方法的修正沒有比較好的想法。

(3)第三次做業:

    UML

 

 

 

    複雜度分析

    a、dependency

 

 

 

    b、 complexity

    總結

     此次做業的依賴性除了MainClass由於須要其餘類來輔助執行,因此相對來講大一點其餘還好。複雜度分析圖中,相比於第二次做業,爆紅的方法又加了一個addRequest方法,由於此次做業的調度設計涉及指定樓層,在沒有找到一個統一的方法的時候,只能經過打表的方式進行調度,我以爲或許能夠經過將該函數進一步細化,獲得一個複雜度較好的函數。

(4)plantMUL

 

 

 

4、bug分析

(1)自我bug分析

    互測測到的bug主要是錯誤使用了notify,隨機的喚醒線程使得我一些線程長睡不醒,改爲notifyAll後就不會出現這樣的隨機性了。

   值得一提的是第三次做業的中測,因爲對於notifyAll、wait的理解不夠深刻,致使我在關於wait對象一判斷就喚醒,出現了一些線程wait條件判斷被阻塞,致使測試RE差點死於中測。可是通過這一次我好好學習了notifyAll的使用,發現只有在wait對象狀態發生改變的時候,即true變成false,纔可以notifyAll

(2)hack的bug

    第一次做業hack到的是暴力輪詢的bug;第二次做業沒有hack到;第三次做業hack到的是RE的bug,我以爲應該就是我中測碰到的那個類型的bug。

5、bug策略

   此次hack構造,主要從很長時間再來一我的hack暴力輪詢,經過一次來不少人hack調度分配線程衝突。可是碰到一些評測到沒法復現的bug仍是感到多線程就是運氣的問題,可是若是一個安全的程序不該該依賴於運氣,應該要有一個充分的維護。與第一單元相比,這一次的做業在調試,bug復現的難度上大大的提升,並且有時候原理搞不明白,也很難找到bug。因此我認爲仍是應該要細細的分析程序,經過自動測試的方式只能是一種手段,還應該從從線程的程度上考慮,避免阻塞的狀況發生。

6、心得體會

   在這一次做業中,從線程安全上考慮應該要理清楚線程的執行順序,線程共享的對象。設計原則上應該儘量的符合開閉原則,減小一些重複操做和閉合操做,防止死鎖的產生。多線程的體驗中,我學習到了一些設計模式,雖然理解還不是很透,可是對於多線程的協做感到十分的神奇,並且感受十分的接近現實生活。並且感受學習寫程序,不該該依賴於專有的設計架構,應該多想一想多嘗試一些原理。否則再後續調bug,可能本身就算是小黃鴨講解程序,也仍是不會找到程序的bug。同時這種多線程的使用,在過程式代碼中是至關難實現得,又進一步瞭解了面向對象程序!

相關文章
相關標籤/搜索