2013-09-23 72 views
4

我正在閱讀一些用於學習目的的android基本遊戲技巧。在Android遊戲循環中同步

我遇到了一些代碼,用於同步遊戲循環線程上使用的SurfaceHolder對象的訪問,爲什麼這是必要的?

示例代碼SDK /樣品/機器人-18 /遺留髮現/ LunarLanderLunarView.LunarThread類:

public void run() { 
    while (mRun) { 
     Canvas c = null; 
     try { 
      c = mSurfaceHolder.lockCanvas(null); 
      synchronized (mSurfaceHolder) { 
       if (mMode == STATE_RUNNING) updatePhysics(); 
        synchronized (mRunLock) { 
         if (mRun) doDraw(c); 
        } 
       } 
     } finally { 
      if (c != null) { 
       mSurfaceHolder.unlockCanvasAndPost(c); 
      } 
     } 
    } 
} 

所以這一段代碼獲取從mSurfaceHolder對象在畫布上,然後將其接入在繪製畫布時鎖定。 爲什麼需要同步?

我認爲這不是,因爲請求畫布和繪製它的唯一線程是遊戲循環運行的線程。

the documnetation of SurfaceHolder.lockCanvas()說,它會獲得一個內部鎖,直到unlockCanvasAndPost()被調用,那麼爲什麼額外的同步?

回答

1

如果你看看你給的參考,完整的報價是:

如果沒有返回null,該函數內部保持鎖定,直至相應unlockCanvasAndPost(Canvas)的調用,防止SurfaceView從創建,在繪製時破壞或修改表面

我的重點 - 請注意,閱讀不在列表中。因此lockCanvas不會停止正在讀取。我猜想額外的同步意圖是爲了確保其他線程在當時不能讀取 - 這很有道理,因爲您打電話給updatePhysics,這可能會讓其他讀者感到困擾。

+0

好的,我理解讀鎖定部分,但是'updatePhysics'是從同一個線程調用的,它是繪製圖形的同一個線程,所以不能併發訪問'mSurfaceHolder'。我仍然不明白。 – Paul

+0

在檢查其同步時,很難辨別程序員的意圖。通常情況下,程序員正在防禦晦澀的競爭,只有當用戶做了一些愚蠢的事情時纔會發生。 「太多鎖定」的唯一真正反對意見是如果結果很慢並且在這種情況下這不太可能成爲問題。總之 - 我會說這是偏執狂(但無傷大雅)編碼。 – OldCurmudgeon

1

查看源代碼的其餘部分,SurfaceView線程外的其他一些操作也在mSurfaceHolder上同步。因此,我的信念是mSurfaceHolder被用作方便的'鎖'對象來同步線程和應用程序的其餘部分之間的狀態。