2015年8月6日 星期四

關於Thread多線程

過去幾個禮拜在做「在Google Map上記錄使用者行走路徑」的功能...

(基於業務需求,不能附上詳細的程式碼。)

製作的過程中碰到最重要的幾個問題:

1.GPS的精準度和效率。
2.如何在行走過程中,開啟和關閉地圖,(地圖只是記錄行走路徑的附屬功能,可以獨立開啟跟關閉,)但又不會影響紀錄的效率和整體操作的流暢性。
3.紀錄行走的路徑資料量吃光了記憶體。

關於1,結果有點無解。

關於3,用即時的SQL讀寫來解決。

關於2,解決的過程中刷新了我對Thread的應用和設計心得.......




Thread的意義在於「不要讓單一項工作/任務吃光所有CPU的運算資源」,所以它會建議設計師在迴圈或程式碼中埋下Thread.sleep,來讓目前的工作/任務先暫時停止工作、把結果保留下來,然後處理其他工作。



我個人接觸Thread的初體驗是遊戲設計中的「畫面更新」功能。

畫面更新速率要穩定!(不穩定可以視為Thread設計失敗!)

但這是「畫面更新」的要點,而不是「Thread設計」的基本技巧,導致我一直以來在Thread的設計上,都會將Thread設計得過於僵硬強勢!──Thread結構都類似「畫面更新」的「無止盡的執行下去、直到程式關閉為止。」(這樣的Thread執行或許很穩定,但卻很難關掉、很難即刻反映APP的生命週期或開關。)

我想這是因為遊戲中都會將要運算和更新的資料量控制在一個穩定的範圍內,例如敵人數量要穩定、圖層數量要穩定。

所以不管是遊戲數值的運算、或畫面的更新,這兩個Thread的運算效率通常都會很穩定。(偶爾會有「爆擊」、「連續技」、「超大範圍攻擊」等事件發生,.......能否處理好就看工程師的功力了。)



但這次在更新地圖路徑的繪圖需求上,卻是完全彈性的!

資料量從一開始可能十筆二十筆,在五分鐘後會爆增到一百筆兩百筆,再十分鐘後又會增加到八百筆九百筆。

資料的量非常不穩定,所以「遊戲軟體」中「畫面更新」的Thread設計原則必然不適用!

將「數據運算」和「畫面更新」做成兩個完全平行、且穩定持續運作的Thread並不適合在這個運算資料量一直增加的設計中。



所以兩個Thread要從平行改為主從式設計。

一個Thread為穩定持續運作,另一個則被前面的Thread動態的生成啟動或關閉,...但在我這次的工作中,只有啟動、不需要關閉。(「畫面更新」Thread不需要循環執行,單一的功能執行完、則整個Thread關閉丟入記憶體回收列中.....,下次要更新畫面時,重啟一個Thread。)

這還是需要一些參數上的設計,例如「畫面更新開始」和「畫面更新結束」,畫面更新如果開始,就主Thread就不會再發出畫面更新的Thread,直到畫面更新結束為止。

(其實這是可以同一個參數解決的。)



這樣設計後,畫面的更新效率或許不太理想,時不時「使用者當下位置」跟「路徑線」會有點差距.......

但APP的整體操作完全不受影響。

沒有留言:

張貼留言