在三次做業中,我都採用了經過一個共享隊列,採用輪詢(非暴力輪詢)的方法進行信息的傳遞,在初次接觸多線程時,因爲懼怕產生死鎖,故最初採用了這樣的方法,但這樣的信息交互方法,相對於普通生產者消費者模型的wait()
和notify()
方法確定效率較低,有許多無用的查詢,在之後的練習中,仍是須要改爲wait()
和notify()
。python
在考慮同步控制的方法時,我是採用syncronized
修飾臨界區的方法來進行防止多個線程同時對一個臨界資源進行操做。在剛接觸多線程時,我記得最清楚的點就是ArrayList
是線程不安全的,Vector
是線程安全的。因爲對於這一區別的不瞭解,我就在電梯第二次做業中,將全部的ArrayList
都替換成了Vector
,想以此來保證多線程的安全性。在後來本身的測試和資料的查閱中,我發現Vector
的線程安全體如今其方法的原子性,但在符合操做中仍是得使用鎖的方法進行互斥訪問,因此在這裏ArrayList
和Vector
並無差異。算法
在第一次做業,因爲沒有性能分,就直接照搬傻瓜調度的方法進行程序的構建。安全
在第二次做業,採用(僞)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;
}
因爲第二次做業問題沒有發現,致使了我在第三次做業的負優化。(因爲一個指令派發給某一個電梯,可是因爲他沒有捎帶走,只能等他運行完其餘指令才能運送這一指令,形成了很大的性能損失)測試
三次做業的類圖以下所示:優化
本次做業較爲簡單,未發現什麼問題atom
和第三次做業大致一致,在第三次做業中詳述spa
在第三次做業中,主要的問題仍是電梯過於複雜,因爲我分配請求是根據當前狀況下哪個電梯運送這個請求最快來指派電梯,因此須要計算cost,爲了減輕代碼量就把這一部分放在了電梯中澤娜加了電梯的複雜度,這一部份內容本應該所有有調度器負責。解耦合狀況我認爲也還能夠。
優勢:在計算時間時,將部分實現代碼放在了電梯中,減小了總體的代碼量
缺點:在計算時間時,將部分實現代碼放在了電梯中,增長了電梯和調度器之間的耦合,不利於類與類職責的拆分
第一次和第二次做業在公測和互測中沒有bug。
在第三次做業中因爲一些事情,太遲進行代碼的編寫,致使對於代碼的測試不足,一個小小的疏漏公測出了一個bug。
for (int i = 1;i <= 3;i++) {
upDispatch(i);
}
for (int i = 1;i < 3;i++) {
downDispatch(i);
}
//漏了一個=,致使調度器一直有一個15-1的人沒法派分出去,致使了程序的不能結束。
因爲對於多線程有了大概清晰的瞭解,而且採用輪詢的方法,沒有出現多線程相關的蜜汁bug
我採用python生成隨機數據,再使用管道實現不斷喂數據給程序,再對結果進行正確性檢測。在測試別人的程序時,使用隨機數據進行測試,測出了4,5個bug,效果仍是不錯的,在第二次做業時,因爲知道有同窗被發現了bug,因此針對其代碼結構編寫了測試樣例,找到了一個bug。其餘所有采用隨機測試的方法,將錯誤同窗的輸入複製到其文件夾中,以隨機字符串給其命名以防止覆蓋。
這個單元的測試和上個單元的測試是徹底不一樣的,由於這一次若是不使用評測機就根本沒辦法進行測試,評測機的編寫也是一個小難點。並且第一次能夠只依靠手動羅列各類狀況手寫測試樣例來找bug,而此次即便構造出測試樣例也沒辦法測試。
1:不能使用基本數據類型做爲共享對象,最初使用Boolean來做爲共享對象,後來發現這不是引用傳遞,而是值傳遞,致使程序不能正常結束。
2:Vector的安全性只體如今其方法的原子性上,在複合操做中不保證原子性。