總結性博客作業
?
第一次作業
(1)從多線程的協同和同步控制方面,分析和總結自己三次作業的設計策略。
?
第一次作業為單電梯傻瓜調度,可以采用生產者——消費者模型,是一個有一個生產者(標準輸入電梯請求),一個消費者(電梯),中間的托盤共享數據為請求隊列的模型。由于電梯沒有容量限制,因此生產者生產的請求可以實時加入到請求隊列中。消費者(電梯)每次從請求隊列中取出一個請求并執行。只需要保證對請求隊列的操作互斥就可以了。由于elevator的結束條件是input結束并且請求隊列為空,所以elevator需要感知input是否結束,對此采取將input線程作為elevator的一個數據成員,這樣就可以使用input.isAlive()來判斷input線程是否結束。
?
(2)基于度量來分析自己的程序結構度量類的屬性個數、方法個數、每個方法規模、每個方法的控制分支數目、類總代碼規模計算經典的OO度量畫出自己作業的類圖,并自我點評優點和缺點,要結合類圖做分析通過UML的協作圖(sequence diagram)來展示線程之間的協作關系(別忘記主線程)從設計原則檢查角度,檢查自己的設計,并按照SOLID列出所存在的問題
?
(3)分析自己程序的bug分析未通過的公測用例和被互測發現的bug:特征、問題所在的類和方法特別注意分析哪些問題與線程安全相關關聯分析bug位置與設計結構之間的相關性
第一次沒有踩到bug。
?
(4)分析自己發現別人程序bug所采用的策略列出自己所采取的測試策略及有效性,并特別指出是否結合被測程序的代碼設計結構來設計測試用例分析自己采用了什么策略來發現線程安全相關的問題分析本單元的測試策略與第一單元測試策略的差異之處
第一次也沒有檢查到別人的bug
?
(5)心得體會從線程安全和設計原則兩個方面來梳理自己在本單元三次作業中獲得的心得體會
只需要對共享數據的操作進行互斥就可以了。
?
第二次作業
(1)從多線程的協同和同步控制方面,分析和總結自己三次作業的設計策略。
?
第二次作業為單電梯ALS調度,仍舊可以采用生產者——消費者模型。
與第一次作業的區別在于:
- 電梯到了某一層樓后,需要檢索請求隊列中所有請求,取出其中能夠被電梯捎帶的請求,并放入電梯的loader隊列里面。
- 第二次作業對CPU時間進行了限制,所以再采取輪詢的方式獲取請求是不行的。必須使用wait,notify方法。在請求隊列為空并且沒有輸入的時候,讓電梯線程wait,當再次有輸入的時候讓輸入線程去喚醒電梯線程,這樣做有效減少了CPU時間。
- input與elevator是兩個平等的對象,將input作為elevator的數據成員是不合理的,因此設置一個共享變量hasInput,初值設置為true,當hasInput為true的時候,電梯線程就不會結束。只有當Input線程結束,由Input線程將hasInput設置為false,并且當請求隊列為空的時候,電梯線程才能結束。
?
(2)基于度量來分析自己的程序結構度量類的屬性個數、方法個數、每個方法規模、每個方法的控制分支數目、類總代碼規模計算經典的OO度量畫出自己作業的類圖,并自我點評優點和缺點,要結合類圖做分析通過UML的協作圖(sequence diagram)來展示線程之間的協作關系(別忘記主線程)從設計原則檢查角度,檢查自己的設計,并按照SOLID列出所存在的問題
?
(3)分析自己程序的bug分析未通過的公測用例和被互測發現的bug:特征、問題所在的類和方法特別注意分析哪些問題與線程安全相關關聯分析bug位置與設計結構之間的相關性。
自己的bug在于elevator的run方法少寫了一行listout,導致有些人沒有出電梯。
?
(4)分析自己發現別人程序bug所采用的策略列出自己所采取的測試策略及有效性,并特別指出是否結合被測程序的代碼設計結構來設計測試用例分析自己采用了什么策略來發現線程安全相關的問題分析本單元的測試策略與第一單元測試策略的差異之處
測試策略是自己編寫邊界數據。
?
(5)心得體會從線程安全和設計原則兩個方面來梳理自己在本單元三次作業中獲得的心得體會
從第二次作業中,我踩到一個巨坑。那就是不能notify沒有獲得鎖的線程,一旦notify沒有獲得鎖的線程,就會報錯。所以要寫成這樣:
synchronized(共享數據){
notify();
}
?
第三次作業
(1)從多線程的協同和同步控制方面,分析和總結自己三次作業的設計策略。
?
第三次作業為多電梯調度,還是采用生產者——消費者模型。
與第二次作業不同的地方在于,由于是多電梯,不光生產者與消費者對共享數據的操作要互斥,消費者與消費者之間對共享數據的操作也要互斥。
?
請求隊列采用二維Arraylist模型,只有每個一維Arraylist的第一個任務可以被電梯接受,每次電梯執行完一個請求就將它從請求隊列中移除。
?
(2)基于度量來分析自己的程序結構度量類的屬性個數、方法個數、每個方法規模、每個方法的控制分支數目、類總代碼規模計算經典的OO度量畫出自己作業的類圖,并自我點評優點和缺點,要結合類圖做分析通過UML的協作圖(sequence diagram)來展示線程之間的協作關系(別忘記主線程)從設計原則檢查角度,檢查自己的設計,并按照SOLID列出所存在的問題
?
?
(3)分析自己程序的bug分析未通過的公測用例和被互測發現的bug:特征、問題所在的類和方法特別注意分析哪些問題與線程安全相關關聯分析bug位置與設計結構之間的相關性
mainrequest進入電梯導致超載。我的架構是mainrequest獨立于請求隊列而存在,因此主請求進入時電梯人數忘了加1。
?
(4)分析自己發現別人程序bug所采用的策略列出自己所采取的測試策略及有效性,并特別指出是否結合被測程序的代碼設計結構來設計測試用例分析自己采用了什么策略來發現線程安全相關的問題分析本單元的測試策略與第一單元測試策略的差異之處
測試策略是猜想哪些地方可能出錯,針對性的編寫邊界測試數據來測試自己程序,debug時采用打印中間信息的方式。
?
(5)心得體會從線程安全和設計原則兩個方面來梳理自己在本單元三次作業中獲得的心得體會
?
由于有些請求不能直達,需要拆分,而拆分的方式又有很多種,而電梯又是根據請求隊列來運行的,所以在請求得到時就要進行拆分,我這里采用了傻瓜拆分策略,先看A能否直達,再依次看B,C,再看AB組合,AC,BC依次檢索。這里的拆分策略就是一個可以優化的點。
多線程的bug有時候不能復現,所以一組測試數據需要多測幾次。
自己寫的測試程序的時間不一定是標準的,可以采用研討課大佬同學講的標準化時間來輸入。