2013-06-04 29 views
1

我試圖強制執行一對Android線程之間的同步以實現遊戲編程目的。我已經分配了一個處理大多數職責的遊戲線程和一個渲染線程,它負責交換緩衝區和渲染。當我第一次詢問線程同步時,我將ConditionVariable對象稱爲強制線程阻塞直到併發任務完成的有用工具。ConditionVariable可以防止兩個線程同時運行

我的源代碼是這樣的:以正確的順序執行

  ... 
      final ConditionVariable bufferLock = new ConditionVariable(); 
      final ConditionVariable cycleLock = new ConditionVariable(); 

      bufferLock.open(); 
      cycleLock.open(); 

      Runnable bufferSwapTask = new Runnable() 
      { 
       public void run() 
       { 
        swapBuffers(); 
        bufferLock.open(); 
       } 
      }; 

      Runnable renderTask = new Runnable() 
      { 
       public void run() 
       { 
        Log.d(TAG, "drawAll"); 
        drawAll(); 
        cycleLock.open(); 
       } 
      }; 

      while(!halt) 
      { 
       if(!init) 
       { 
        synchronized (userInputLock) 
        { 
         fetchUserInput(); 
        } 

        processUserInput(); 
        gameLogic(); 

        bufferLock.block(); 
        cycleLock.close(); 
        renderThreadHandler.post(renderTask); 
        recycleDisplayObjects(); 
        enqueueDisplayTree(); 

        cycleLock.block(); 
        bufferLock.close(); 
        renderThreadHandler.post(bufferSwapTask); 
       } 
      } 
      ... 

這樣的事情,但不是我所預期的性能水平。而且,當我激活DDMS方法跟蹤時,我發現DVM實際上會中斷和阻塞每個線程,以允許其他線程恢復,以強烈暗示兩個線程僅由一個CPU處理的方式來回切換。

我已經使用ReentrantLocks很好的同時處理結果,那麼爲什麼ConditionVariable有這種效果?

回答

2

Android上的Linux內核嘗試避免在內核之間移動線程。如果一個線程是「可運行的」(即可以運行但正在等待另一個線程)一段時間,內核可以決定將其遷移到另一個內核。

如果在前面的實現中,其中一個線程會持續運行,它可能會使其他線程保持「runnable」足夠長的時間以使內核遷移它。新的實施方案可能會以較小的步驟進行並落在門檻以下。

FWIW,其他人一直對此感到困惑,例如, herehere