oo第二單元作業主題為多執行緒,具體的任務是要實現乙個五棟樓的電梯系統,三次作業分別為每棟樓乙個電梯,每棟樓多個豎向電梯且引入橫向電梯,支援換乘且電梯引數可自定義,下面我分享一下我在本單元的學習心得和作業完成情況。
在整個第二單元中,我為了盡可能做到執行緒安全均使用了hashmap作為容器,在往hashmap中新增object的時候就不用在外面設定同步塊了,但要注意的一點是,在遍歷hashmap的時候一定要將其寫在同步塊內,例如下面的**塊:
synchronized(hashmaptotr**erse)
}
同時,在整個第二單元中,我引入了兩個object例項:obj和outputlock,obj的作用是所為wait和notify的物件例項,具體用法的乙個例子如下:
synchronized(obj)
// if there is no request
synchronized(obj)
而outputlock則是對輸出加鎖,避免輸出時間戳不遞增的情況。
由於第一次作業不涉及樓層間的互動,同時乙個樓層也只有乙個電梯,因此無需設定排程器。
第一次作業整體來說比較簡單,難點主要是對於多執行緒和生產者消費者模型的初步理解。第一次作業需要關注的點在於電梯的排程,我採用的是sstf排程,即電梯每到一層,便會遍歷電梯內外所有請求,找出離當前樓層最近的請求,然後往請求方向移動一層或者開關門接送乘客。sstf排程的優點是程式實際執行的realtime期望較小,但缺點是realtime方差較大,身邊就有同學因為使用sstf而導致強測出現了rtle的情況。
本次作業我強測掛了一半的點,因為我偷懶把電梯設定成開關門期間只許進出一名乘客,因為本來電梯開關門一次就可以完成的任務,我的電梯最多要開關門12次,這必然會導致rtle。
在互測環節,由於我在b房,所以當我拿評測機跑其他同學的**的時候,幾乎所有人都出現了執行緒不安全的問題,最後我也是成功刀中了十幾人次,為爛掉的強測回了一些血。同時,由於我的程式本身不存在排程和執行緒安全問題,我在互測中沒有被hack。
本次作業和hw2一樣,相對於上一次作業新增的內容都很大,但由於本次作業不涉及換乘,因此難度個人任務不像hw2相比hw1跨度那麼大。
本次作業相比於第一次作業,我對於每個請求的處理和遍歷都加上了同步鎖,因為可能存在乙個請求被兩個電梯搶上,從而出現乙個人進入兩個電梯的情況,具體實現如下面的**塊所示:
synchronized(hashmaptotr**erse)
}}synchronized(request)
在第二次作業中,我對於需求的排程採取的是自由競爭策略,即「誰搶到就算誰的」,因此我沒有單獨開乙個排程器類去排程所有請求。
本次作業相比第一次作業我進行了兩部分的修改,一是將sstf排程修改成了look排程,二是新增了橫向電梯,對於橫向電梯,我依然是採用的look排程,但由於其是環形設計,我對look排程進行了微調,即:移動方向上兩座樓內沒有需求就使得電梯移動方向轉變。同時,我也解決了第一次作業電梯開關門一次只能進出乙個人的問題。
本次作業我是比較幸運的,在ddl前十分鐘發現了程式中的乙個執行緒不安全的bug並及時修改提交,使得我在互測及強測中沒有被發現bug,不過事後我使用沒修改的版本交強測也ac了。在互測中,我針對超載測試了幾個資料點,可惜最後沒有hack到任何一名同學。
本次作業中需要我們支援電梯的換乘,同時電梯的各項引數可以自定義。
在本次作業中,我並沒有引入新的同步塊,與第二次作業的同步塊和同步鎖保持一致。
在本次作業中,我對於需求的排程採取的依然是自由競爭策略,因此我依然沒有單獨開乙個排程器類去排程所有請求,但本次作業需要我們實現換乘,我的實現方法是在請求被輸入進來程式的時候,就根據橫向電梯的情況把它拆成1-3個子請求,這裡涉及到了換乘樓層的選擇,我與官方策略的換乘樓層選擇一致,即所有可以同時停靠請求起點和終點樓座的橫向電梯中,離請求起點和終點距離之和最小的橫向電梯的樓層為換乘樓層。
可以看到,本次作業我的主要修改就是增加了橫向電梯資訊類和子請求類,本質上這兩個類都是為了請求拆分所服務的,因此電梯執行的排程我幾乎沒有進行修改。
首先要指出,我在三次作業中整體架構是保持不變的,因此三次作業的協作圖的整體框架基本是一樣的,這裡放出第三次作業的協作圖供大家閱讀:
在互測中,我針對請求拆分構造資料hack到了一名同學。
然後就是arrive的輸出邏輯問題導致強測**,第一次體會到c房的恐怖...
實在是...難 以 評 價
在本單元的學習中我初步體會了多執行緒程式設計的思想,初步體會了多執行緒的生產者消費者模型。
本單元我做的比較好的地方是對於執行緒安全的處理,在本單元三次作業中沒有一次作業產生了執行緒安全問題。而我做的不好的地方,甚至可以說是致命的地方只有乙個字:懶。仔細想想,第一次和第三次作業寄強測或多或少就是因為懶。同時,第二次和第三次作業中我也沒有去使用調取器去優化電梯的排程,不過身邊很多人用排程器導致了效能分不公升反降。
可以說,oo最難的兩個單元已經過去,接下來的三四單元可能難度會稍微簡單一點,但是也依然不能掉以輕心,還是要有問題多提問,防止這次單元的「悲劇」在接下來的時間裡反覆重演。
OO第二單元總結
本單元的作業總體來說比較愉快,畢竟不像上次一樣次次重構。本單元為電梯系列問題,涉及到多執行緒問題。簡單起見,我使用的是生產者 消費者模式。本次作業要求實現單部可稍帶電梯。看完題目後我認為生產者 消費者模式非常適合解決這個問題。本次電梯我採用的是look方法。本方法核心即在於電梯方向的判斷,這在dis...
OO第二單元總結
共享資料類 在總結後面的3.基於度量的程式結構分析部分,本人根據展示的uml類圖更加詳細的講解了具體的協同結構工作原理。通過對實現以上操作的共享資料類中的方法設定synchronized,從而實現執行緒對共享資料的訪問同步。ocplsp ispdip 根據以上類圖,分析本次作業設計思路如下 2 根據...
OO第二單元總結
第二單元總結 第一次作業 思路與反思 uml類圖 度量分析 耦合度 第二次作業 思路 第二次作業與第一次的迭代在於電梯增加 人數限制 樓層改變,我依舊用的look演算法,在第一次作業的基礎上修改細節即可,多部電梯要求實現執行緒安全,由於我使用的look演算法,電梯盲目執行,沒有更高階的排程,只需要在...