java多线程实现电梯_面对对象第二单元总结 - 电梯(java多线程)
概述
剛剛過去的oo第二單元主要是來訓練我們java多線程設計。
借助電梯這個載體,逐步深入,線程的信息交互,控制也隨之復雜。
盡管,我本單元成績不是很好看,但是,確實學到了不少東西。
下面,我就借助分析三次作業,來談下我的收獲。
作業分析
第一次作業
(1)任務分析
本次作業需要模擬一個多線程實時電梯系統,從標準輸入中輸入請求信息,程序進行接收和處理,模擬電梯運行,將必要的運行信息通過輸出接口進行輸出。
本次作業電梯系統具有的功能為:上下行,開關門,每運行一層的時間為固定值,開關門的時間也為固定值。
電梯系統可以采用任意的調度策略,即上行還是下行,是否在某層開關門,都可自定義,只要保證在系統限制時間內將所有的乘客送至目的地即可。
電梯系統在某一層開關門時間內可以上下乘客,開關門的邊界時間都可以上下乘客。
至于調度算法-簡單FAFS(傻瓜調度即可)
(2)設計策略
請求模擬器作為一個線程,負責接受在線請求并負責將請求放入請求隊列中。
電梯作為一個線程,從請求隊列get到所需請求并模擬電梯行為
請求隊列是請求模擬器和電梯線程的共享對象,負責完成線程通信,控制。
其實,第一次作業比較簡單,只需要考慮以下幾個問題
問題1電梯如何完成請求
先接到請求發出者,然后完成該請求。在第一次作業中,我們無需判斷電梯運動方向,所以這個問題就比較簡單了,只需要sleep盲目模擬即可
問題2電梯線程什么時候死亡?
請求模擬器沒有更多請求產生 & 請求隊列等待人數為0 & 電梯中沒有人
問題3線程通信,控制
第一次作業,輪詢無礙,至于同步問題,給請求隊列的get() put()函數加鎖即可
(3) 度量分析
代碼規格
類圖
復雜度分析
可以看出來本次作業的工作量不是很大
SOLID原則分析
本單元,因為我沒有使用繼承和接口,所以在下面的SOLID原則分析中,在下僅僅分析SRP和OCP
首先,我這次嚴格進行了SRP-輸入類只負責輸入,電梯只負責運行,調度器只負責存儲請求隊列。
由于是第一次作業,我暫時未考慮可擴展性
線程協作圖(后面倆次作業的線程協作圖也是如下,就不多次展現了)
Bug分析
第一次比較簡單,僥幸沒有中招
第二次作業
(1)任務分析
這次作業較第一次的改動如下
1:需要改變自己的調度方法(指導書推薦為ALS調度)
2:改變樓層限制 -3層 - -1層 和 1層 - 16層,每到一層樓需要輸出Arrive at 當前樓層
3:為了便于攜帶,需要區分主副請求
此外需要注意的是,因為需要輸出Arrive信息,所以我們需要設定電梯運行方向
為了滿足評測限制,需要將調度算法改為ALS,并盡量使用notify(),wait()完成線程控制
(2)設計策略
(我沒有按照指導書的方法區分主副請求,我是按最遠的為主請求。)
1:當請求模擬器無法產生更多請求 & 請求隊列為空 & 當前主請求完成后,結束當前電梯線程
反之,將成功獲取一個主請求后,進入執行主請求的時候,每到一層,看當前樓層是否有可攜帶的人。
如有,看是否改變當前電梯的需到達的最高樓層和最低樓層。當電梯無人的時候 外加 第一個人接到后,結束本次任務。
2:get()函數如果發現請求隊列為空的話,wait()阻塞,等待請求模擬器產生請求的時候,notifyall()通知消費者
我這樣設計的話,固然性能分可能高點
但是有很大缺點,最嚴重的一點就是乘客體驗可能極其差(強烈譴責),根本不可能用在實際生活中。
(3)度量分析
代碼規模
類圖
復雜度分析
emmm,可以看出來,我有些操作設計的不是很好,原因主要在于我在Elevator.run()中寫了電梯的運行過程
其實,按照老師業務邏輯和行為邏輯分離的思想,我應該單獨領出來該部分成為一個函數,來實現業務和邏輯分離
SOLID原則
本次作業和上一次作業基本架構相同,符合單一責任原則(SRP),
在本次作業中我沒有考慮多電梯的可拓展性,所以我認為在開放封閉原則(OCP)上做的還不是很好,其他原則在本次作業中也無需考慮。
Bug分析
剛剛提到了第二次作業較第一次作業,我們需要完成電梯運行方向的設置。因為我改變了ALS調度策略,導致電梯中可能存在需要電梯向上和需要電梯向下運行的乘客
但是由于我的方向判斷錯誤(始終以主請求來判斷方向),導致電梯最后直接奔向十八層地獄,枯了,還是私下測試過少,導致的問題
第三次作業
(1)任務分析
本次作業,需要完成的任務為多部多線程智能(SS)調度電梯的模擬
較前面幾次作業的區別
1:多部電梯
2:載客限制
3:可到樓層限制
4:不同電梯運行速度區別
(2)設計策略
問題1換乘問題
設置person類 (我認為乘客應該了解自己如何換乘),一開始首先利用課程提供的接口來獲取乘客的信息(id,起始樓層,終止樓層)進行檢測,看單部電梯是否可以完成該請求,如若不能的話,就按照一定策略,設置該乘客的換乘樓層。
(比如可以固定一樓為換乘站,但是可以進行優化,通過比較乘客的起始樓層,和到達樓層來選擇換乘樓層)
等該乘客換乘出電梯的時候,立刻根據其的信息,生成新的請求放入調度器的請求隊列
問題2電梯結束條件
這次的電梯線程終止條件發生了變化,記得加上條件 無運行電梯(為此,我在調度器中增加一個變量flag代表當前daintiness運行數量,當一個電梯當前任務完成時,cnt--并notifyall()(為了完成換乘問題,以防需要換乘的電梯已經wait()))
問題3如何分配乘客
我依舊采取電梯之前自己來搶請求的策略。
我給每個乘坐者person設置了一個權限數組,代表可以乘坐哪部電梯。每部電梯在攜帶或者get主請求的時候,僅僅只能擁有當前電梯權限的電梯
所以第三次作業的框架較第二次的框架沒有什么大的變化
(3)度量分析
代碼規模
類圖
復雜度分析
SOLID原則
本次作業輸入線程負責向請求隊列輸入,電梯線程可能會向請求隊列輸入和輸出,
但是我沒有專門設置接口管理輸入和輸出,在單一責任原則(SRP)上可能做的不是很好。
至于擴展性方面,我設置Typecheck類來完成可達性檢查,如果增加電梯數量的話,可以比較輕松的解決
二、互測策略
第二單元的互測難度真心比第一次的大很多,因為一個人寫評測機的工作量較大,所以我自己僅僅寫了一個分析最后輸出結果是否正確的程序
至于如何測試代碼,我是分為以下幾個策略的
1:測試同時間多位顧客的請求可否完成
2:測試是否可以完成攜帶工作
3:測試是否可以正常線程結束工作
因為多線程的錯誤難以復現,有時候自己明明測試出來錯誤,卻發現無人中刀
所以本周互測積極性不是很高
三、收獲與感想
盡管,這一單元,我的成績不是很理想,但是還是學習到了很多多線程知識。
多線程設計第一點就是要保證線程安全!線程安全!線程安全!
第二點就是要選擇好的線程通信方法,輪詢是不可能的,最起碼也要采用wait(),notify()
這個的使用就需要注意,要不然很有可能就是死鎖
不過,死鎖了也不要過于著急,在wait(),和notify()周圍printf一下,可以解決絕大部分問題
(printf大法好)
對了,千萬不要忘記一個好的架構!要不然,一次重構一次爽,全部重構火葬場
至于優化,千千萬萬要保證程序的正確性,否則可能得不償失(別問我,怎么知道滴!)
總結
以上是生活随笔為你收集整理的java多线程实现电梯_面对对象第二单元总结 - 电梯(java多线程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ios mysql install_快速
- 下一篇: 50元怎么存进银行卡