OOP第二次做業

OOP第二次博客做業

(1)從多線程的協同和同步控制方面,分析和總結本身三次做業的設計策略

在三次做業中,我都採用了經過一個共享隊列,採用輪詢(非暴力輪詢)的方法進行信息的傳遞,在初次接觸多線程時,因爲懼怕產生死鎖,故最初採用了這樣的方法,但這樣的信息交互方法,相對於普通生產者消費者模型的wait()notify()方法確定效率較低,有許多無用的查詢,在之後的練習中,仍是須要改爲wait()notify()python

在考慮同步控制的方法時,我是採用syncronized修飾臨界區的方法來進行防止多個線程同時對一個臨界資源進行操做。在剛接觸多線程時,我記得最清楚的點就是ArrayList是線程不安全的,Vector是線程安全的。因爲對於這一區別的不瞭解,我就在電梯第二次做業中,將全部的ArrayList都替換成了Vector,想以此來保證多線程的安全性。在後來本身的測試和資料的查閱中,我發現Vector的線程安全體如今其方法的原子性,但在符合操做中仍是得使用鎖的方法進行互斥訪問,因此在這裏ArrayListVector並無差異。算法

在第一次做業,因爲沒有性能分,就直接照搬傻瓜調度的方法進行程序的構建。安全

在第二次做業,採用(僞)Look算法進行調度,可是因爲本身的設計失誤使得本身作了一個零優化。(在電梯進行調度接人時,例如電梯上行接一個要下行的人,我會將請求指令派發給電梯,卻沒有電梯的調度中增長目的樓層的刷新和檢測樓層是否有人須要進出,也就致使了增長的優化毫無心義)多線程

第三次做業,我沿用第二次的架構,調度器先靜態拆分不可直達的指令,再經過請求的優先級(例如-3-3優先級最高)來派發指令架構

while (true) {
           /*to split the personRequest*/
           checkSplit();
           for (int i = 1;i <= 3;i++) {
               upDispatch(i);
          }
           for (int i = 1;i <= 3;i++) {
               downDispatch(i);
          }
           if (waitList.isEmpty() && upList.isEmpty() &&
                   downList.isEmpty() && inputFlag.getFlag()) {
               managerFlag.setFlag();
               break;
          }
           Main.sleep(breakTime);
}

同時根據電梯的運行情況選擇運送時間最短的電梯進行運送。性能

private ConcreteElevator chooseBestE(PersonRequest personRequest) {
       long leastTime = 50000;//the max time
       ConcreteElevator bestE = elevators[0];
       for (ConcreteElevator concreteElevator : elevators) {
           if (concreteElevator.isCarry(personRequest, isBypass)) {
               long time = concreteElevator.costTime(personRequest, isBypass);
               if (leastTime >= time) {
                   bestE = concreteElevator;
                   leastTime = time;
              }
          }
      }
       return bestE;
  }

因爲第二次做業問題沒有發現,致使了我在第三次做業的負優化。(因爲一個指令派發給某一個電梯,可是因爲他沒有捎帶走,只能等他運行完其餘指令才能運送這一指令,形成了很大的性能損失)測試

(2)基於度量來分析本身的程序架構

三次做業的類圖以下所示:優化

 

本次做業較爲簡單,未發現什麼問題atom

 

 

 

 

 

和第三次做業大致一致,在第三次做業中詳述spa

 

 

 

 

在第三次做業中,主要的問題仍是電梯過於複雜,因爲我分配請求是根據當前狀況下哪個電梯運送這個請求最快來指派電梯,因此須要計算cost,爲了減輕代碼量就把這一部分放在了電梯中澤娜加了電梯的複雜度,這一部份內容本應該所有有調度器負責。解耦合狀況我認爲也還能夠。

 

總體類的分配我以爲仍是較爲合理的,沒有出現類的職責嚴重混淆起來的狀況。

優勢:在計算時間時,將部分實現代碼放在了電梯中,減小了總體的代碼量

缺點:在計算時間時,將部分實現代碼放在了電梯中,增長了電梯和調度器之間的耦合,不利於類與類職責的拆分

 

基於SOLID原則的分析:
Single Responsibility Principle:基本遵循,除了在上面寫的計算時間時致使了電梯多承擔了一部分功能
Open Close Principle:沒有很好的實現,在進行功能的添加時,會對一些模塊進行修改,說明在最初進行架構設計時並無很好的考慮接下來的可能需求,之後須要多對於此進行分析,在設計一個好的架構,可以實現對擴展開放、對修改關閉
Liskov Substitution Principle:沒有體現,因爲在這三次做業中都沒有用到繼承,因此沒有涉及。
Interface Segregation Principle:沒有體現,在這三次做業中沒有出現多個類共享一個接口的狀況,因此沒有涉及。
Dependency Inversion Principle:在第三次做業中,限制了每一個電梯所能到達的樓層,但在以前我並無預估到這一狀況的發生,因此將這一屬性內嵌在了電梯的實現中,在以後的做業中,必定要好好的分析需求,使得方法依賴於抽象而不是具體實例。

(3)分析本身程序的bug

第一次和第二次做業在公測和互測中沒有bug。

在第三次做業中因爲一些事情,太遲進行代碼的編寫,致使對於代碼的測試不足,一個小小的疏漏公測出了一個bug。

for (int i = 1;i <= 3;i++) {
upDispatch(i);
}
for (int i = 1;i < 3;i++) {
downDispatch(i);
}
//漏了一個=,致使調度器一直有一個15-1的人沒法派分出去,致使了程序的不能結束。

因爲對於多線程有了大概清晰的瞭解,而且採用輪詢的方法,沒有出現多線程相關的蜜汁bug

(4)分析本身發現別人bug所採用的策略

我採用python生成隨機數據,再使用管道實現不斷喂數據給程序,再對結果進行正確性檢測。在測試別人的程序時,使用隨機數據進行測試,測出了4,5個bug,效果仍是不錯的,在第二次做業時,因爲知道有同窗被發現了bug,因此針對其代碼結構編寫了測試樣例,找到了一個bug。其餘所有采用隨機測試的方法,將錯誤同窗的輸入複製到其文件夾中,以隨機字符串給其命名以防止覆蓋。

這個單元的測試和上個單元的測試是徹底不一樣的,由於這一次若是不使用評測機就根本沒辦法進行測試,評測機的編寫也是一個小難點。並且第一次能夠只依靠手動羅列各類狀況手寫測試樣例來找bug,而此次即便構造出測試樣例也沒辦法測試。

(5)心得體會

1:不能使用基本數據類型做爲共享對象,最初使用Boolean來做爲共享對象,後來發現這不是引用傳遞,而是值傳遞,致使程序不能正常結束。

2:Vector的安全性只體如今其方法的原子性上,在複合操做中不保證原子性。

3:考慮在須要用視有多個讀者的時候使用讀寫鎖纔來提升多線程對於數據訪問的效率。

相關文章
相關標籤/搜索