第二次博客作業
面向對象第5-7次作業總結
最近的三次作業都是有關java多線程的應用問題,而且是三個完全不同的問題,對於剛開始對多線程一無所知的狀態,很難理解多線程問題的內核所在。只能是照著例子來生搬硬套。但隨著對作業的不斷更改和評測,也在不斷加深自己對多線程的認識和了解。而且對多線程的不同線程的交互,線程安全,多線程程序的性能,多線程的隨機過程等這些最重要的問題也進行了學習和掌握。
三次作業代碼分析
1.多線程電梯
設計策略:
對於多線程電梯這次作業,由於是第一次接觸多線程問題,所以對多線程的理解和使用還不夠深刻,所以設計的時候使用了生產者和消費者的樣例。對於輸入隊列建立單獨的線程,然後三個電梯為三個消費者,在輸入隊列後建立三個電梯分別的隊列,做為三個生產者,他們之間用三個線程安全的托盤進行交互。這樣就構造了一個三生產者三消費者的設計結構。
UML圖:
對於其分析來看,發現代碼的圈復雜度比較高,進一步分析發現是調度器類和電梯類的復雜度比較高:
調度器對電梯請求的分類和電梯對上下行的判斷結構比較復雜是導致復雜度較高的原因,但是我認為這屬於比較正常的設計。這些的功能性是無法替代和簡化的。
類圖:
這就是輸入線程producer通過托盤tray和調度器線程交互,調度器schedu通過三個托盤tray1和電梯線程customer交互。
設計不足:
由於過於依賴三個托盤,所以造成三個電梯之間信息無法準確交互,電梯內指令容易分配,但是涉及樓層指令時由於這種結構無法準確地判斷指令地分配,所以出現樓層指令地混亂。
2.IFFF文件管理
設計策略:
對於此次作業,我並沒有使用快照對監控目錄進行不斷地掃描對比,而是每當產生一個新的請求,就單獨為監控文件建立對應的觸發器線程對單個文件進行掃描對比。同樣使用了生產消費和托盤,每次確定了監控對象後就建立一個掃描線程和處理線程,中間用線程安全的托盤進行資源共享。掃描線程不斷對文件所在目錄掃描,每次掃描完處理線程只針對監控文件進行對比,決定處理方式。
UML:
分析發現圈復雜度依然有點小高……
進一步確定是重命名線程的run方法的復雜度較高。我覺得是自己的判斷條件較大導致的,所以對重命名線程的判斷方法和處理方法應該進行簡化和優化來降低圈復雜度。
類圖:
輸入線程確定監控對象,為每一個監控對象建立對應的四個觸發器之一,觸發器由兩個線程組成,掃描線程和觸發器對應的處理線程。Record為記錄輸出線程。
設計不足:
由於在設計之初指導書中並不支持對目錄的監控,所以我的設計方案沒有考慮對目錄的監控,由於只對單獨的文件進行掃描對比,所以當目錄中產生新文件時因為沒有對比數據所以無法對其添加新的監控。所以無法處理新文件的出現。
3.出租車調度
設計策略:
建立乘客請求隊列和100個出租車線程。輸入線程不斷獲取請求並將其加入隊列中,調度器線程共享請求隊列,並在請求加入隊列的三秒內不斷判斷出租車位置並將符合條件的出租車加入此乘客的搶單名單,並在三秒後判斷出租車是否接單。判斷完畢後將請求從隊列中刪除。
UML:
對其中的復雜度進行分析:
是提供的gui程序復雜度較高,對於出租車類來說,則是因為狀態轉換和判斷的復雜度較高,對於輸入,是對乘客請求的判斷和分割處理復雜度高,對於地圖則是讀取文件的復雜度較高。
類圖:
運行流程:
二、BUG分析
1.產生bug
三次作業,第六次作業因為個人信息而無效。第五次作業產生了8個錯誤,這8個錯誤都是因為對於樓層請求的分派考慮的不夠充分產生的,也是由於設計結構的不合理導致的資源共享的問題。
2.分析策略
(1)對於捎帶請求進行充分的測試
(2)對於recover和監控對象為目錄的情況進行重點測試
(3)對於最短路徑和一輛車參與多個搶單的情況進行測試
三、心得
經過三次作業,對java的多線程問題有了更加直觀和深入的理解。對於線程安全,線程交互,線程隨機過程等都需要進行具體和合理的設計。簡化共享對象、對共享對象的線程安全的封裝等都是多線程裏面非常重要的部分。而我的設計策略也在發生著變化,由最初的生產者消費者模式,到後面的簡化線程由調度器線程直接進行分配調用,大大減少了線程數目,在一定程度上優化了程序的性能。
第二次博客作業