第五次做業java
UML & Mertrics算法
電梯的調度問題,實質上就是任務的請求與分配問題,筆者在第五次做業中採用簡單的「生產者-消費者」模型,創建了Din
線程做爲生產者解析輸入並增長運載請求,創建Elev
線程進行輸出,待處理數據由主控類Ctrl
維護,並做爲電梯「調度器」,前二者的操做由線程安全的Ctrl
負責,後兩次做業也延續這樣的架構,事實是無需重構也應付得了本次迭代。但筆者請求隊列與調度器一體化,且只有一級調度,致使主控類異常臃腫。安全
第六次做業數據結構
UML & Mertrics多線程
還是老三樣,第六次做業中擴展功能比較容易實現,進行相關類的方法擴寫,主要是實現多電梯線程,筆者Ctrl
類的處理不是很好,下一次重寫了Ctrl
架構
第七次做業測試
UML & Mertrics線程
架構上沒有大的改動,爲實現換乘功能,筆者創建了MyReq
類存儲PersonRequst
與乘客現處樓號,並面向過程根據換乘地圖爲各型電梯創建了樓層映射機制設計
notify()
條件,竟然喚起了RUNNALBE
的線程,因爲Ctrl
是共享的,致使輸入被電梯線程阻塞,好在最終肯定了進入wait()
的條件。ElevatorInput.getElevatorNum()
,而是用(new Scanner(System.in)).nextInt()
,System.in
被輸入接口與Scanner
共享,致使輸入緩衝區線程不安全,筆者此次屬實拉了胯了,直接白給愉悅送走C
型電梯上的乘客想去樓4
時,筆者直接給他送到樓3
,但樓3
只有C
能去,B
接不到,此次強測也是差點翻車了,不過三次做業筆者的總體結構仍是能夠的,經過嚴格控制synchronized
語句塊的分佈與使用,三次做業除了這些bug也沒有出現過死鎖或是數據冒險啥的難以復現的bug1
,3
,15
是最特殊的3個換乘點,也能夠枚舉全部請求後排除直達請求進行換乘的完備hack第五次做業只創建了輸入線程Din
,電梯線程Elev
,看到一些朋友把調度器也整成線程我是沒想到的,Din
負責向Ctrl
輸入數據,並在輸入及結束後喚醒全部WAITING
的Elev
,Elev
的結束條件是沒有待調度請求而且Din
在結束後設置了無輸入的全局變量。具體調度策略方面,選用LOOK
算法,但不管SCAN
仍是LOOK
,都損失了一個方向上的請求信息,總感受不太好。因而以後筆者就真香GREEDY
了,打造了純貪心的電梯調度與電梯間調度策略3d
第六次做業改動很少,主要是改變了Ctrl
中的數據結構適配多部電梯,另外的重頭戲就是電梯間調度,筆者在本次將單電梯改成貪心電梯,與同窗交流中有的是用平均分配、隨機分配來分派任務到各個電梯,但筆者仍是採用了電梯間自由地貪心競爭策略。緣由是,設想有兩架Elev
,一臺空載,一臺載有乘客,從同一樓號出發,對於某一請求而言,載人Elev
由於電梯內請求而停靠或轉向的平均機率更高,空載更有可能搶到請求。實際上載客越少越能直接相應電梯外請求,這有效減少某些電梯一直空轉的概率,從而自動實現了優先級任務分配,提升了Elev
並行率,每次上一我的也能夠Thread.sleep(5)
提升並行率。還有就是這樣不用寫二級調度了
第七次做業,鑑於要實現換乘,有必要維護須要換乘乘客的當前樓號,因而筆者新建了MyReq
類改進PersonRequst
,對於上文2、
中notify
了運行線程的bug,筆者也找到了安全方便的方案
for (int i = 0; i < elevNum; i++) { if (elevs.get(i).getState().equals(Thread.State.valueOf("WAITING"))) { synchronized (elevs.get(i)) { elevs.get(i).notifyAll(); } } }//先判斷是在wait()再notifyAll();
同時要注意線程安全的坑,筆者是保證全部Elev
最後一塊兒DEAD
的,防止要換乘的電梯早退
解決線程設計後,煩人的換乘問題來了,各型電梯的樓號定義域A = [-3, 1] ∪ [15, 20]
,B = [-2, 15] - {3}
,C = [1, 8] * 2 - 1
,找到換乘點(A ∩ B) ∪ (A ∩ C) ∪ (B ∩ C) = (C - {3}) ∪ {-1, -2}
,筆者並不想寫二級調度,就創建了地址轉換,考慮Elev
對MyReq
的解析,咱們只要在電梯A-C
下完成MyReq
在電梯內和在電梯外的樓號轉換就行,實際上完成前者就行,若電梯內getToFloor()
非法,就將目的地改成換乘路徑最短的換乘點。電梯外的話,先假設上電梯,轉換後若目標就是當前樓層,就保留本來目的地,不然直接上電梯。筆者真是懶死了,這類特定情境問題仍是最好畫圖分析或打表,別像筆者敗在細節。
筆者本單元的做業效果並不理想,仍是對於線程安全的理解不深,以及沒有注重多線程程序設計中的細節問題致使bug,筆者仍是對本身的調度器耿耿於懷,筆者理應實現隊列,調度分離的,這樣的調度器耦合度過高了。