OO學習體會與階段總結(多線程程式)

来源:https://www.cnblogs.com/Cookize/archive/2018/05/01/8976321.html
-Advertisement-
Play Games

前言 在最近一個月的面向對象編程學習中,我們進入了編寫多線程程式的階段。線程的創建、調度和信息傳遞,共用對象的處理,線程安全類的編寫,各種有關於線程的操作在一定程度上增加了近三次作業的複雜度與難度,帶來了不小的考驗。本文通過分析總結近三次作業的完成情況,分享我對與多線程編程的一些見解與體會。 作業總 ...


 前言

  在最近一個月的面向對象編程學習中,我們進入了編寫多線程程式的階段。線程的創建、調度和信息傳遞,共用對象的處理,線程安全類的編寫,各種有關於線程的操作在一定程度上增加了近三次作業的複雜度與難度,帶來了不小的考驗。本文通過分析總結近三次作業的完成情況,分享我對與多線程編程的一些見解與體會。

 

 


 

作業總結分析

多線程電梯調度

(1)題目簡述

  實現具有捎帶功能的電梯調度系統,調度電梯數量為3部。

(2)程式設計

  • 本系統的大致結構與之前的單線程電梯調度系統類似,主要由輸入處理、請求調度、電梯模擬三大部分組成。
  • 根據行為的併發特征,為這三大部分各設計了一類線程來實現其功能。分別為輸入監聽線程、請求調度線程、電梯線程。
  • 系統中的共用資源主要是請求隊列,根據請求隊列的類型分成了輸入隊列與執行隊列。二者繼承了請求集合類,並將這兩個類編寫成線程安全類。
  • 根據生產者-消費者模型構造線程交互方法。
  • 具體類圖如下:

  • 時序圖:

(3)程式分析

  • 複雜度度量:

     

  • 分析:
    • 在存儲請求隊列時採用了數組的數據結構。進行請求隊列的增減操作時需要遍曆數組,導致了相關方法迴圈複雜度較高。由於運用了長度變數控制遍歷的邊界,這些方法不會出現危險。可以考慮使用集合類管理此類數據,以減小代碼的複雜性,增加可維護性。
    • 線程類的run方法過於複雜,使得該方法的複雜度異常的高。出現該問題主要由於對於線程類的功能的理解不夠到位。應當將線程的行為細化,並根據線程運行時需要執行的不同操作編寫相應的方法以供線程調用。這樣能提高線程類的可維護性。
  • 數據統計:

    

 

(4)問題分析

  本次作業的問題主要出現在以下兩個方面:

  • 捎帶請求處理:本次作業沒有採用前幾次作業處理捎帶請求的方法,而是根據電梯的運行將分配到的請求按照到達先後順序構造隊列,電梯按照隊列頭改變運行狀態即可。但是在將新請求插入隊列的部分,邊界判斷出現了錯誤,導致當電梯停止時新請求的插入位置出錯。最終使電梯運行路線出錯。
  • 輸出格式:對於不合法的輸入,輸出時的格式不對。更改輸出格式可以改正。

  本次作業使第一次編寫多線程程式。由於對於每個線程的運行過程的理解不足,我在最初的程式構架時遇到了比較大的困難。尤其是在共用類中鎖的運用以及線程類的run方法的功能的設計上,經歷了多次刪除重寫的過程。在一定程度上,這導致了我在類的設計、調度演算法設計等方面有了不少疏忽。最終使得本次作業的完成效果一般。此外,線上程調度方面,本次作業較好的運用了課內講的模型。通過這次的鍛煉,我對於多線程編程的大體框架有了比較深刻的認識,為接下來的學習打下了鋪墊。


 

IFTTT

(1)題目簡述

  實現IF-THIS-THEN-THAT的文件監控與操作系統。

(2)程式設計

  • 經過分析,程式大致分為文件快照獲取、監控事件觸發、監控事件任務執行三部分。

  • 根據行為的併發特征,為每個監控事件開啟一個線程,實現監控功能;並且設計一個負責實時輸出的線程。
  • 具體類圖如下:

  • 時序圖:

(3)程式分析

  • 數據統計:

  

  • 複雜度分析:

  

  • 分析:

    • 在構造文件系統的遍歷樹是採用了一維的線性數據結構,每次獲取快照時都需要按深度遞歸遍歷監控範圍內的所有文件,導致獲取快照的相關方法的複雜度較高。在優化的方面,可以考慮改用集合類中的樹結構或者哈希表的方式對監控範圍內的文件進行預處理(如編碼),減小之後的工作量。此外還可以直接使用現有庫中的獲取快照的方法。

    • 本次作業對與線程類中的run方法進行了一定的精簡。相較於上次作業,複雜度有了一定的降低,但仍然是所有方法中最高的。可能的原因是我在最初設計時為單一線程分配了過多的功能。就本次作業而言,可以按照觸發器的不同將監控線程進行分化。而且還可以將快照獲取功能分離成單一線程,通過一個線程安全類與監控線程傳遞信息。

(4)問題分析

  本次作業的問題主要出現在文件地址的管理方面。在程式中,每個文件都使用的是絕對地址格式。絕對地址有多種可識別格式,但通過File類提供的方法從File對象中獲取的絕對地址僅有一種格式。由於在前後快照對比是通過字元串比較實現的,所以可能由於格式問題導致錯誤。將格式同一後可以解決。

  在本次作業中最重要的部分就是文件信息的同步。由於文件操作是線程不安全的,所以在完成作業的過程中,我用了相當多的時間在設計線程安全類和快照獲取功能上,最終獲得了不錯的效果。但在類功能的設計上還顯得有些冗雜,有挺大的改進空間。

 


模擬計程車打車系統

(1)題目簡述

  實現100輛計程車的搶單調度系統。

(2)程式設計

  • 交互關係分析:

    • 乘客交互的數據特征:提供請求產生時間、乘客位置信息、目的地位置;返回請求的處理結果。
    • 乘客交互的時間特征:不定時產生乘客請求;請求產生3s後返回處理結果。
    • 計程車交互數據特征:獲取計程車的位置信息、服務狀態和信用信息;返回其搶單結果和需要服務的乘客位置信息與目的地位置。
    • 計程車交互時間特征:以100ms為周期獲取。
  • 對象識別與構造:

    • 需要管理的數據及管理手段:
      1. 乘客的請求:

        • 監聽獲取乘客發出的請求。
        • 維護接受的請求集合。
      2. 乘客請求的響應視窗:

        • 根據請求的位置與時間建立相應的搶單視窗。
        • 維護相應視窗集合。
      3. 計程車:

        • 維護計程車信息的更新。

        • 維護計程車集合。

  • 識別併發行為:

    • 系統與乘客之間交互相對獨立,由於只由控制台輸入,使用一個線程設計用於與控制台輸入交互。

    • 計程車的行為具有顯著的重覆模式,並且相對獨立,使用一種線程設計,分別描述每一輛計程車行為。

    • 對於獲取的乘客請求的處理與分配具有重覆性,並且相對獨立,使用一種線程設計來實現功能。

    • 信息輸出相對獨立,使用一個線程實現。

  •  具體類圖如下:

  • 時序圖:

(3)程式分析

  • 數據統計:

  

  • 複雜度分析:

  

  • 分析:

    • 相較於上次作業,本次作業方法的複雜度有了明顯的降低(不考慮現成的GUI代碼)。在最初設計的時候,我就考慮到了SOLID等原則,並儘量使設計的類符合以上的原則,做出了風格上的改變。其中線程類的設計上,儘量分配更少、更簡潔的功能,使其僅需完成線程部分必要的代碼。從而使得整個程式的可維護性與可讀性有了相當大的提高。

(4)問題分析

  在測試階段我的程式沒有被髮現問題。但是在自己檢查的時候發現了不少的潛在問題:

  • 地圖管理:本次作業我使用了gui中給好的地圖管理類,使用矩陣管理地圖。每當計程車接單時都需要調用廣度遍歷方法來獲取最短路徑。這使得計程車在路徑的選擇上缺乏功能延展性,只能走最初設定好的路線,無法適應路況的變化。
  • 計程車管理:在本次作業中,我為了簡單將所有的計程車都管理在了同一個數組中,將計程車狀態保存在了計程車各自的對象中。如果能將不同狀態的計程車分離,用不同的策略去管理,則能夠使程式的延展性更高。

 


總結

  經過了這三次的多線程編程作業,通過分析作業中的問題,我對於線程的調度與線程的安全有了相當深入的認識。從巨集觀上來看,每個線程都在同時運行,但微觀上看他們是在JVM的調度之下按原子操作交替執行。如果每個線程間相互獨立,JVM調度的不確定性不會影響程式的可再現性。但就像電梯中的請求隊列、IFTTT中的文件信息、計程車系統的請求和計程車信息,每個線程間難以避免地會有共用的數據,此時就需要通過同步、互斥的手段防止JVM調度的不確定性破壞程式的可再現性。通常,通過鎖機制就能夠實現這些功能。但是,在共用關係比較複雜的情況下,單純的使用鎖機制並不一定能夠達到預期的效果。這時就需要一種模式化的線程安全保護措施。那就是線程安全類。編寫線程安全類就好比為已有的功能代碼加上一層外皮,其內部代碼保證功能的實現,外部介面保證入口的互斥,從而實現線程安全。但這又帶來了另一個問題:同步部分的代碼長度對多線程效率的影響。進而對於臨界區的功能安排應當儘量精簡,以避免對多線程機制的浪費。

  此外,經過了對面向對象思想的學習,我認識到了面向對象程式設計的12大基本原則,並且將其實踐到最近的一次作業當中。在親自編寫代碼的過程中,我體會到這些原則最核心的想法就是:設計具有層次性、代碼具有可延展性。在設計時就要從最外層的交互設計,一層層深入,到內部對象的建模、對象間交互,再到類內部的設計。這個設計就是對整個環境與系統的逐層深入,將各個功能逐層分離,最終形成類似樹狀的類設計。而在編寫代碼的時候不應當僅關註於當前的功能實現,更應當想到更多同類型的操作。換句話說就是編寫出的方法、類不應當進能夠實現特例操作,而更應當面向更為抽象、更為通用的層次上。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 支持離線 Web 應用開發是 HTML5 的另一個重點。所謂離線 Web 應用,就是在設備不能上網的情況下仍然可以運行的應用。 開發離線Web 應用需要幾個步驟。首先是確保應用知道設備是否能上網,以便下一步執行正確的操作。然後,應用還必須能訪問一定的資源(圖像、Javascript、CSS等),只有 ...
  • 本文內容: 層疊性 繼承性 優先順序 權重計算方法(特異性) 首發日期:2018-05-01 層疊性: 層疊性是指當一個標簽被設置了多個重覆的樣式的時候,一個屬性會覆蓋另外一個屬性。 比如:先給div設置背景顏色為紅色,然後設置背景顏色為粉紅色,那麼最終顏色可能為紅色,也可能為粉紅色(明顯的兩種顏色設... ...
  • 三維變換使用基於二維變換的相同屬性。3D變換功能與2D變換功能相當類似,css3中3D變換主要有4個功能函數: 1、3D位移:CSS3中的3D位移主要包括translateZ()和translate3d()兩個功能函數。 2、3D旋轉:CSS3中的3D旋轉主要包括rotateX(),rotateY( ...
  • 一、JS的變數 1.變數的聲明 2.使用一行代碼強調多個語句。其中b為undefined; 3.JS中變數聲明的註意事項。 ①JS中聲明變數的關鍵字只有var一個,變數的類型取決於所附的值。 如果聲明時未賦值,則返回undefined類型(聲明之後沒有賦值的變數,不是未聲明)。②JS中同一個變數,可 ...
  • 元素(element) 類型:替換和非替換元素 替換元素(replaced element): 用來替換元素內容的部分並非由文檔內容直接顯示. eg:img input 非替換元素(nonreplaced element): 其內容由用戶代理在元素本身生成的框顯示. eg:絕大多數都是非替換元素 基 ...
  • 前端技術之_CSS詳解第一天 一html部分 略。。。。 二、列表 列表有3種 2.1 無序列表 無序列表,用來表示一個列表的語義,並且每個項目和每個項目之間,是不分先後的。 ul就是英語unordered list,“無序列表”的意思。 li 就是英語list item , “列表項”的意思。 你 ...
  • transform轉換屬性的5個值: 1、 translate(x值,y值) 移動效果。 2、rotate(45deg) 旋轉效果。 3、scale(x軸倍數,y軸倍數) 縮放效果。 4、skew(x軸deg,y軸deg) 傾斜效果。 5、matrix() 矩陣 ...
  • 面向對象第八次作業 代碼分析 第五次作業 多線程電梯 UML圖和協作圖 代碼複雜度分析 這次作業的主要難點在於對於多線程的理解和實踐,一方面由於老師上課講的著急,內容也更多的偏向JVM的介紹,因此對於多線程編程的一些思路和方法沒有多少瞭解,另一方面由於時間不足也沒有時間去更詳細的自學多線程,因此基本 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...