首先這三次作業總體都是關於電梯,所以電梯肯定要抽象出乙個類。然後聽老師上課說的,排程器要有乙個類。還要乙個主線程來開始其他執行緒,以及乙個用來讀取輸入的執行緒。
所以總體我寫了四個類。電梯類:模擬電梯執行,持有屬性為執行速度,到達樓層,所在樓層,執行方向等,還有自己的request佇列,存放的是在本電梯內的乘客。排程器類:其實相當於負責看管公有屬性的乙個類,我這裡設計的主要是等待佇列和結束訊號。然後我選擇了同步方法,所以基本上都是在這個類裡選擇了一些方法進行上鎖,等同於鎖了排程器對應的物件。讀入類:這個類也是乙個執行緒,負責不停地從標註輸入讀入personrequest然後放入排程器中,並且負責傳遞結束訊號。主線程main類負責啟動計時器和啟動讀入和電梯執行緒。
第五次作業是傻瓜電梯(電梯裡只有乙個人),第六次作業開始就有了順帶策略。我認為順帶就是在爬樓的時候,在每一層判斷是否要帶其他人。這個工作被我交給了排程器,然後在每一層增添了get on 和 get off功能。還有乙個問題就是什麼人可以被攜帶。這裡主要是排程策略比較難,**書寫方面也就是在加幾個if else,沒有什麼難度。在第六次作業的指導書中提供了一種思路,就是分主請求和副請求的思路,我六七次作業都是按照這個思路來寫的。後來我想了想,發現我面對這種沒見過的電梯(目的選層電梯),做排程策略的時候太過死板。其實雖然我們的**寫的是虛擬的電梯,但是我們現實生活中的方便快捷的電梯執行思路也是值得參考的。如果加入這些思考的話,主請求的更換是提高順帶效率的必要選擇,但是我當時的排程策略沒有考慮到這方面。結果導致第六次作業的效能分近乎為零。
第七次作業加入了多部電梯,調整了每部電梯的執行速度,最難受的是加入了每個電梯可以抵達的樓層,導致出現了需要轉梯的情況。從排程策略的角度,需要合理協調三部電梯,完成轉梯,並提高效率。另一方面,增加了兩部電梯,從執行緒安全的角度,又多了一些顧慮,需要更加合理的設定鎖。
像老師說的一樣,其實這次作業並沒有在排程策略上為難我們,只是想要完成作業而不太考慮效率的話,做法就比較簡單。我是找了兩個公共層,即所有電梯都可以到達的層,1層和15層。需要轉梯的高層統一在15層轉,其他的都在1層轉。這個排程策略不是很通用,但是在本次作業設定的三個電梯中,在轉梯方面是比較合理的,只有個別的請求,比如從3層到14層的請求,會比理想情況多跑個一兩層。這次作業我做的比較差的地方是多部電梯協作來提高效率的地方,比如有一名乘客要從1層到20層,所以a電梯先把它接走了,過了一會又有一名乘客要從1層到20層,按我的排程設定,a電梯會過來跑兩趟,可是實際上可以讓b電梯幫忙先從1層送到15層,這樣一會a電梯可以少跑幾層,總體時間就變短了。還有因為涉及到電梯的容量,所以會有雖然滿足要求但是上不了電梯的乘客,這些乘客也可以讓其他電梯幫忙來送一半路程(還是我在看測試樣例的時候發現的)。這裡我幾乎沒有寫出來,感覺如果考慮到這種情況,排程策略會變得很複雜……
除這兩個部分,在加入兩部電梯的情況下,如何判斷是否結束執行緒成了乙個有點難度的問題。等待隊列為空,end訊號設定和自己的電梯隊列為空不再是結束執行緒的全部條件,因為其他電梯還在執行,而電梯中的乘客可能是一名需要轉梯的乘客。而且因為用了wait,所以最後設定每個電梯執行緒結束時都要再notifyall一下,避免有的執行緒一直被阻塞著沒法結束,而且滿足所有電梯內部都沒有人,等待隊列為空且end訊號設定的情況下(即真的結束),不能再wait了。
第五次作業類圖
第六次作業類圖
第七次作業類圖
時序圖我只畫了第七次作業的時序圖(因為我還不太會畫時序圖的原因,不額能準確地畫出這幾次作業時序圖的區別)。我覺得我對這幾個執行緒的設計還是比較合理的,基本上能夠完成三次作業的基本要求,至於效能上的問題,多出現在排程策略上。
我看了一些其他人的**,發現他們有些人會設計更多的類。從度量分析來看,我這次的每個方法規模都不大,但是乙個類裡含了太多的方法,尤其是排程器類。也許可以再分些小類,但是我沒想到要怎麼分比較好。
公測用例和互測用例均為發現bug
其實我這個單元對互測都不是很關注……因為總覺得這個單元能進入強測的**都太不好找bug了。而且在本地端測試這種需要特定時間投放資料的**對吾等菜雞來說太難了。真的很好奇出現hack一百多次的大佬是怎麼辦到的。
第一次接觸執行緒方面的**,完全體會到了它的麻煩的地方。也許寫的時候思路清晰,想著到時候執行緒應該怎麼跑怎麼跑,結果真跑起來完全另一種情況。以前依賴的除錯也完全gg,編譯器自帶的除錯完全無法除錯多執行緒,可以說怎麼除錯都是對的。除錯只能用print,真的是非常難受了。設計的時候,要對執行緒的同步和非同步很了解,且清楚每個執行緒的狀態,阻塞態的執行緒要被喚醒,不然最後結束不了。
執行緒安全就是上鎖的問題。基本上就是給共享資料上鎖,但是上鎖涉及到鎖的太多效率低,鎖的太少鎖不住,也很難判斷。而且沒被鎖住的**也要關注,確定是不會威脅執行緒安全的地方。
OO第二單元部落格
一 概述 本單元通過多執行緒實現電梯排程,和上一單元相比較,更加側重於執行緒的安全的模式。相較於上一單元難度有提高,整體來看,沒有第一單元的學習結果好,三次作業中第一次第二次作業比較順利,第三次作業因為執行緒安全的問題最後是無效作業,比較讓人頭痛。在排程策略上三次作業都選擇了指導書中的als排程策略...
北航2020OO第二單元部落格作業
本次作業需要實現一部簡單電梯的執行,很自然的,我選擇將本次作業的三個部分,讀入資料 排程資料 電梯執行作為三個執行緒來執行。其中讀入資料的執行緒比較簡單,根據提供的介面使用方法順序讀入即可。排程資料我實現了乙個排程器類,用於管理兩個佇列,乙個是讀入資料的佇列,乙個是給電梯分配任務的佇列。電梯作為乙個...
OO第二單元作業總結
0.前言 轉眼間物件導向課程已經到了第二階段了,在第二階段裡共發布了三次pta程式設計作業,本次部落格主要針對於這三次作業的總結。作業過程總結,oo設計心得,測試的理解與實踐,課程收穫,對課程的建議。1.作業過程總結 總結三次作業之間的知識迭代關係 第一次作業 水文資料校驗及處理 蒙特卡羅方法求圓周...