OO電梯做業總結算法
這三週的做業和課堂內容以及OS的課上內容都相同,都是關於多線程方面的知識。在此次做業中由淺入深佈置了三項多線程電梯方面的做業,讓咱們在實踐中感覺了多線程的工做原理以及各項須要注意的要素。編程
1、第一次做業多線程
第一次做業是典型的生產者消費者問題,只不過生產者沒必要考慮容器裝滿的特殊狀況。在此次電梯做業中電梯只須要將乘客送往目標樓層,不須要解決沿路搭順風車等其餘須要解決的特殊狀況。當負責輸入的生產者中止時,設置一個共享的結束變量結束整個電梯的運行,整個電梯的運行結構以下圖所示:架構
如圖所示,整個電梯總共包含2個線程,即電梯線程和輸入線程,二者經過結束信號進行通訊。同時二者共享一個共享變量:等待隊列。在多線程環境下勢必會出現二者共同訪問致使數據冒險的狀況。我採起的解決方法是將等待隊列類中的每一個函數設定爲靜態函數,並加上synchronized修飾。經過百度和自身的實踐,這樣操做的實際效果是對類自己進行加鎖,即當一個靜態函數被調用時禁止其餘靜態函數被調用。這樣操做的確可行,可是因爲是在函數上加鎖,性能方面不如對特定變量,但好處是可以有效地確保正確性。函數
本次做業的類圖以下所示:性能
代碼分析以下:學習
能夠看見在電梯類中個人寫法沒有作到徹底對任務進行細分,而是一個run方法走到底,所以代碼的複雜性較高。在接下來的任務中我注意到了本身的問題,對任務進行更細的劃分。測試
BUG分析優化
這一次做業因爲比較簡單,在互測以及強測中都沒有發現任何BUG。spa
第一次電梯做業總結
第一次做業是對多線程的試水,在其中我初步感覺到了多線程的設計風格,同時大體確立了電梯問題的整個架構。在接下來的做業中都是沿用輸入隊列,等待隊列以及電梯3類的架構進行設計。
2、第二次做業
這一次的電梯做業相比上一次的電梯做業增長了2個難點。第一,這一次的電梯是ALS電梯,須要額外考慮2個環節。首先電梯在上升時須要考慮對同方向乘客的捎帶,同時因爲電梯內部可能有多於一個乘客的狀況,所以須要額外增長一個隊列記錄電梯內部的人員請求。第二,這一次做業增長了對於CPU運行狀況的檢查,所以沒法在這一次做業中使用輪詢算法,必須運用鎖控制查詢,下降CPU使用率。
受到OS課程的影響,相比較synchronized,notify(),我偏向更加簡單直接的Semaphore,所以在此次做業中我主要使用Semaphore實現進程同步和互斥。
首先列出此次做業的主要流程架構:
捎帶的解決方法如圖中所示。首先創造運行隊列,將電梯中的全部人的請求加入運行隊列。其次在每一層都檢查等待隊列中是否有知足捎帶條件,若是有則加入運行隊列中。最後再談談我是怎麼解決輪詢問題的,我所採用的方法是最簡單的方法,即在每次搜索結束以後進行sleep操做,減小CPU使用。固然合理利用信號量確定是最高效的解決方案,所以在第三次做業中我採起了另外一種方案。
如下是本次做業的類圖以及代碼分析:
因爲此次電梯做業中啊須要使用到大量的if判斷,包括電梯的運行方向,查找操做以及判斷當前層數是否爲0等,所以此次的代碼複雜度廣泛較高。能夠改進的作法是對函數功能進行進一步的細分。在這一次做業中爲了更高的準確性和代碼的直觀性,我沒有進一步細分,致使代碼複雜度較高。
BUG分析
在中測中主要出現了一個BUG,就是CPU超時,經過sleep()即可順利解決。然而強測只得了26分,緣由特別簡單,也特別愚蠢。在電梯向下運行進行順帶判斷時,不慎將>寫成了<,直接致使測試點全掛。也算是一個教訓。代碼上任何一點微小的錯誤將致使整個崩盤,所以必須在每次中測時作好課下測試,寫本身的評測機,最大限度地杜絕這種狀況再次出現。
3、第三次做業
第三次做業本質上相較於第二次做業增長了2個方面。第一是電梯變多了,所以須要創造更多的運行隊列,同時對等待隊列須要進行訪問加鎖控制。第二點也是此次做業的難點,因爲部分請求沒法由一個電梯完成,所以須要採起合理可行的措施實現多電梯協做。對於該問題的解決我經過改寫PersonRequest類實現,在其中添加了label,realend,available三個變量進行實現,對這種特殊狀況的處理在等待隊列中實現,具體方法以下圖所示:
對於個人處理架構,在此次做業其實還有一個隱藏的難點,那就是一臺電梯關閉時機的判斷。當輸入線程關閉時且等待隊列爲空時不可以關閉電梯,由於label=1的運行隊列中的請求會從新加入等待隊列。解決方法有2個,第一是讓每一個電梯線程可以訪問其餘電梯的運行隊列,當輸入線程關閉,全部的運行隊列都爲空而且等待隊列爲空時,同時結束全部電梯線程。我認爲電梯運行隊列應該由本電梯徹底掌握,所以採起第二種作法,在輸入線程結束而且等待隊列爲空的狀況下,當等待每部電梯都處於查詢等待隊列狀態而且第一次查詢未找到時,將每部電梯的一個特徵變量設置爲1,當全部特徵變量設置爲1時,同時關閉全部電梯。
整體上這一次做業的隊列類以及電梯很好地複用了上一次的做業,對電梯的修改是增長了對label=1任務的特殊處理,對滿員狀況的判斷以及在線程結束時的特殊處理。對隊列的修改包括增長了2個運行隊列,以及在將輸入線程的請求讀入等待隊列時判斷可執行的電梯,寫入available,同時對不可執行的電梯做label=1的特殊處理,第三次做業的類圖以及代碼分析以下圖所示:
這一次的代碼風格明顯有很大的不足之處,緣由之一是這一次的做業大幅度複用了上一次做業的樣板,所以在電梯類中代碼的複雜度較高。第二個不足之處是沒有在電梯類中實現繼承或者建立一個泛化的電梯類。此次做業中三個電梯明顯有很大的相同點,只是在個別屬性上不一樣。將代碼進一步細化而且熟練實現以及掌握繼承是須要在接下來的學習中注意的地方。
BUG分析
這一次的做業比上一次更加悲劇,中測未能經過。最終發現緣由也特別簡單,在電梯順帶時徹底沿用了上一次的模板,忘記進行修改,致使電梯在等待隊列提取請求時根本就沒有判斷當前樓層是否能停靠,直接致使整個測試崩盤。這也給我帶來了第二個教訓,那就是不能太急着寫代碼,而是應該先詳盡地對整個任務進行細節分析,列出全部須要擴展的地方再進行修改,不然就會像這樣在細節處崩盤。
4、互測BUG分析策略
首先這一次的電梯做業測試難度明顯上升,沒法運用簡單的控制檯輸入輸出獲得正確結果,所以在正式進行測試以前我經過討論區的指示本身寫了一個評測機,在另外一個文件中間段輸出本身設定的指令,同時替換輸入線程的方法,經過process類讀取文件中的指令實現按照特定時間輸入的效果。
第一次做業互測:這一次做業的互測其實並無太多BUG能夠發現。我注重兩方面的BUG,一是對電梯關閉時機的測試,第二則是電梯是否可以正確運行。結果並無在互測中發現BUG。
第二次做業互測:這一次做業我受到了屢次攻擊,主要來自於強測的錯誤,將>誤寫成<.這一次的強測我注重兩個方面的測試,首先是在邊緣時間投放測試點,即電梯關門的瞬間投放請求,若是在開門時搜索等待隊列則會錯過該請求。第二是對電梯運行經過0層的測試,在互測中共DE出2個BUG。
第三次做業互測:因爲沒有經過中測,所以很不幸沒有進入第三次互測。
5、心得與體會
多線程處理無疑是每一個程序猿的基礎技能,此次的做業只是爲咱們開了一個很是初步的頭,接下來還有無窮無盡的知識點須要咱們本身去探索。在此次做業中雖然成績不夠理想,可是靜下心來仍是得到了很多的經驗和教訓,包括對編程方法的反思,對細節的把握,以及代碼風格架構的進一步優化,這都是我須要在接下來的做業中不斷改進的地方。在接下來我須要更進一步,積極瞭解閱讀關於JAVA方面的常識和知識,使得本身具備更增強大的專業技能,同時讓本身不至於在細節處再次翻車。