2012-11-02 18 views
0

我有擴展SurfaceView的GraphicView。我需要它來繪製圖形。我還需要onTouchEvent。但問題是...我不知道該怎麼形容它:)這裏是我的代碼:如何同步線程:onTouchEvent和run()?

public class GraphicView extends SurfaceView implements Runnable { 

    private boolean mutexOpened = true; 

    public boolean onTouchEvent(MotionEvent me) { 

     if (mutexOpened) { 

      mutexOpened = false; 

      Log.d("mutex", "ACTION 1"); 

      switch (action) { 

       case MotionEvent.ACTION_DOWN: { 

        int rnd = new Random().nextInt(40000) + 1000; 
        for (int i = 0; i < rnd; i++) {} // it's some long action :) 

        Log.d("mutex", "ACTION 2: down"); 
        break; 

       } 

      } 

      Log.d("mutex", "ACTION 2: end"); 
      mutexOpened = true; 

     } 

    } 

    public void run() { 

     while (true) { 

      if (mutexOpened) {   
       Log.d("mutex", "!!! RUN !!!!"); 
      } 

     } 

    } 

} 

我用互斥技術,它(我想)有能力控制我的線程。但在日誌中我看到以下內容:

!!! RUN !!!! 
ACTION 1 
!!! RUN !!!! 
ACTION 2: down 
ACTION 2: end 

但是爲什麼?爲什麼第二個「!!! RUN !!!!」當互斥鎖關閉時,在「動作1」和「動作2」之間運行?不可能! :)))

我想下一步該怎麼做:

public void run() { 
    while (true) { 
     if (mutexOpened) { 
      mutexOpened = false; // close mutex 
      Log.d("mutex", "!!! RUN !!!!"); 
      mutexOpened = true; // open mutex 
     } 
    } 
} 

,但... FAIL :))的onTouchEvent永遠運行在所有:d)))是否有人知道如何解決這個問題?

+0

@PBrando執行,我想你明白正確。它在第二個線程上運行,但我需要同步這些線程... :) – JavaRunner

回答

1

您必須將訪問mutexOpened同步:run()的可閱讀mutexOpened你把它設置爲false之前,並可打印RUN!打印「ACTION 1」後立即進行。

使用Java關鍵字同步來將訪問同步到mutexOpened。在run()上,你可以使用wait(),它在休眠階段釋放鎖。

如果你使用synchronized關鍵字,你並不需要在所有mutexOpened變量。

public class GraphicView extends SurfaceView implements Runnable { 

    synchronized public boolean onTouchEvent(MotionEvent me) { 


     Log.d("mutex", "ACTION 1"); 

     switch (action) { 

      case MotionEvent.ACTION_DOWN: { 

       int rnd = new Random().nextInt(40000) + 1000; 
       for (int i = 0; i < rnd; i++) {} // it's some long action :) 

       Log.d("mutex", "ACTION 2: down"); 
       break; 

      } 

     } 

     Log.d("mutex", "ACTION 2: end"); 

    } 


    synchronized public void run() { 

     while (true) { 
      wait(100); // Wait 100ms and release the lock 
      Log.d("mutex", "!!! RUN !!!!"); 

     } 

    } 

} 

另外,儘量不要在GUI線程不會執行長操作(即評論「這是一些長期行動」):應該在一個單獨的線程

+0

謝謝你的建議!我嘗試用你的代碼,但它給我一個錯誤:「java.lang.IllegalMonitorStateException:由線程等待對象之前未鎖定()」,這是什麼錯誤呢? – JavaRunner

+0

@JavaRunner你是否聲明方法運行爲「同步」? –

+0

是的,我忘了!它現在有效!謝謝! :) – JavaRunner

1

首先,你還沒有描述你想做什麼爲什麼。其次,你試圖實現你自己的互斥體,這樣做是錯誤的。您嘗試使用的變量甚至不是線程安全的。由於多個線程可能正在訪問它,您無法知道它在任何時間點的狀態。你應該使用AtomicBoolean。

http://developer.android.com/reference/java/util/concurrent/atomic/AtomicBoolean.html

看到這個幻燈片一個很好的介紹多線程設置。

Intro to multi-threading