OO第二次課程總結分析

  前幾回的做業都是單線程的,整體來講和之前的思惟模式和調試等存在着必定的掛鉤,在設計上總體難度還不算太大,此次開始了多線程編程,難度能夠說是質的飛躍,構思上所考慮的不止一點兩點,在總體的基礎上還要考慮線程的同步安全等問題,下面針對三次做業的分析來談談在多線程編程上所犯的錯誤和獲得的收穫編程


 

1、多線程電梯數組

1.設計策略安全

       做爲多線程的第一次做業,又恰逢清明假期,能夠有相對充足的時間來學習多線程的相關知識和進行構思(能夠說這個清明假期過得很是揪心了),由於有了前面兩次電梯的積累,此次關於同質和捎帶的問題並未花太多時間(可是考慮前面的代碼可塑性太差,此次就進行了重構,但核心思想沒變),大部分時間用在了構思三部電梯的調度和安全問題上。多線程的設計與單線程不一樣,在構思實現邏輯的同時還要決定開多少個線程,每一個線程之間的交互影響、線程安全問題等,複雜程度大大提高。在經歷了多天的思考以後,我共設計6個線程(分別爲主線程(Main)、輸入線程(Inputhandler)、調度器線程(Scheduler)及三個電梯線程(Elevator))。共有4個請求隊列(一個總的,3個各自電梯的)。多線程

各個線程的工做以下:架構

  • 主線程(1):其餘線程的實例和啓動
  • 輸入線程(1):在收到輸入結束符以前持續接受控制檯輸入,將有效請求(其中無效和同質都不算有效)放入請求隊列
  • 調度器線程(1):當總的請求隊列不爲空或輸入線程未結束時,不斷掃描總的請求隊列,根據三部電梯狀態和分配原則來將請求分配給合適的電梯
  • 電梯線程(3):當本身的請求隊列不爲空或調度器線程未結束時,不斷掃描本身的請求隊列,根據電梯狀態和請求來執行相應的動做

  關於線程同步控制的考慮,由於請求隊列會涉及到加入請求、刪除請求、從隊列中取出請求及獲取隊列大小等操做,這都是線程不安全的,所以在對隊列的操做上我都上了鎖,一樣,電梯狀態會有改變和獲取的操做,一樣都加了鎖。學習

2.程序結構分析測試

度量分析ui

類圖spa

 

 

sequence diagram線程

 

  我的以爲總體架構還算滿意,各個線程分工較明確,只是在具體實現時有部分代碼顯得臃腫,還未能作到方法功能單一,部分方法用了太多的條件分支,在代碼重用性方面有些欠缺,代碼的可塑性不強。

3.bug分析

  公測有四個樣例沒過,主要仍是栽在了調度線程的問題上,分配請求的方法發生了錯誤,在判斷電梯運動量上未作到安全,考慮不夠周全,致使多個點爆了,另外時間永遠是一個頭疼的問題,公測終究仍是被報了時間的錯誤。互測被找了一個格式錯誤,對格式邊界的把握仍是不夠。

   測他人時仍是先從格式下手,再測一些基本功能的實現(先觀察代碼看必要的地方有無加鎖,再針對性測試),而後從邊界狀況來找到是否符合預期,最後就是用大一點的數據去測。

 


 

2、IFTTT

1.設計策略

  老實說,此次做業的難度比上次的要大,畢竟上次的做業有以前的做業的積累,而且給的時間相對較長,但此次做業不只時間相對少,還涉及到文件系統,光是理解做業需求就花了挺長時間,致使最後做業完成的很糟糕。此次的構思基本就是針對一個做業開一個線程,每一個線程監控每份做業相應的某個觸發器和某個task,而且在建立線程的開始就爲每一個做業建一個狀態快照,線程實時掃描文件,並實時生成更新快照,比較先後快照的不一樣看是否觸發了相應的觸發器,根據相應的觸發器而作出相應的動做。各個線程以下:

  • 主線程:處理輸入,如隊列,線程實例和啓動
  • Detail線程:處理detail這個任務
  • Recover線程:處理recover這個任務
  • Summary線程:處理summary這個任務
  • TestThread線程:提供測試接口
  • Watch(監控)線程:根據觸發器不一樣讓哪一個任務執行

  關於線程安全的考慮,對文件的操做會致使線程不安全,所以這塊利用鎖來實現同步,保證同一時刻只能有一個線程在對文件操做,避免應線程不安全而致使難以預料的錯誤。

2.程序結構分析

度量分析

類圖

sequence diagram

  此次的程序能夠說寫得很糟糕,因爲時間的不足,沒有考慮監控目錄的狀況,而且程序的主線程寫了太多,顯得很臃腫,應該將輸入處理等移出,主線程只負責啓動其餘線程方爲上策。同時,Safefile類忘記提供獲取最後一次修改時間等方法。總之,此次的構思有些問題,程序結構設計的不是很合理。

3.bug分析

  此次互測被找的bug是最多的一次,由於沒有實現目錄的監控,這部分被找了bug,同時,recover也未能實現,致使被測了許多bug,也是對本身的反思吧,畢竟本身沒有實現那部分的功能。

       此次互測就是針對幾種觸發器和幾種任務的組合,一一進行幾組測試,從而找出與預期結果相悖的點,針對找到的點,找到對應的代碼,看關聯的方法或其餘,再針對地找其餘bug。

 


 

3、出租車

1.設計策略

  由於出租車是相互獨立的,互不影響,故考慮每輛出租車一個線程,每輛出租車都有各自的私有屬性,都能進行搶單、運送等動做,且出租車之間沒有交互,各自獨立。同時由於每輛出租車要從搶單出租車中選出合適的,故每一個出租車都設了一個屬於本身的請求隊列,調度器負責爲乘客選擇合適的出租車,出租車負責將乘客送往目的地。所以,程序的線程以下:

  • 主線程:讀入地圖信息、聲明靜態常量、線程實例及啓動
  • 輸入線程:輸入請求並將有效請求(無效、同質均不算)加入隊列
  • 出租車線程(100):出租車的各類運行(隨機跑或按最短路徑跑)
  • 調度器線程:選出搶單出租車並進行派單

  關於線程安全的考慮,本次總的請求隊列是一個共享資源,故是非線程安全的,在對隊列的操做中都加了鎖,由由於調度時要得到出租車的狀態、信用度即位置等,因此在出租車的狀態、信用度及位置等的set,get方法上均加了鎖。

2.程序結構分析

度量分析

類圖

sequence diagram

  此次程序的方法我儘可能地去寫得很短,只實現某一個功能,其餘部分各人認爲寫得算是比較簡潔,但調度器的run方法仍是用了太多的循環和條件判斷,致使度量變紅,這一塊應該改進,搶單能夠另外用一個方法實現,而不用寫在run裏還有Taxi的判斷走哪條路的方法複用性不夠強,代碼的相同地方過多,能夠經過傳目的地參數的方法進行此部分代碼的複用。

3.bug分析

  此次交得急,沒有寫測試接口,被報了一個設計缺陷,同時由於gui中算最短路徑的方法耗時太長,在輸出時我用的是假時間,但gui上跑得較慢,由於這個緣由,接單和服務狀態下車要比等待時跑的慢,被測試者找了bug,還有由於在遍歷數組時條件判斷不夠充足,致使程序在必定間隔內輸入的多條請求引起NULLpoint的crash。

  此次找bug爲了能保證出租車必定能接到單,我找的時候讓出租車初始位置從某個點出發,便於進行測試。

 


 

最後的心得體會

  經歷過這最痛苦的三週,對多線程編程也有了本身的體會。在多線程電梯剛開始使用鎖時,傻傻地鎖住了sleep,致使線程之間不能並行,這個讓我困惑了許久,後來逐漸縮小鎖的方法的範圍才解決。多線程的運行機制比單線程複雜得多,在動手以前要足夠了解這種機制,否則真的發生了預料以外的後果你也會手足無措,因此事先設計構思、想好哪些資源須要共享,哪些須要同步,哪些線程是獨立的,哪些是交互的,我認爲這種考慮在多線程編程中是很是有必要的。

相關文章
相關標籤/搜索