2

synchronized思ったように動かないようです。synchronized同じオブジェクトによる別のコードブロックに関して、括弧内のコードをアトミ​​ックにするべきではありませんか?

コード内でまったく同期していないことがわかりました。

private Object movementMutex_ = new Object();    

// Thread
public void run()
{
    while (run_)
    {
        synchronized(movementMutex_)
        {
            if (timeToMove_)
            {
                Log.v("meh", "timeToMove_ was true, moving");
                makeMove();
                Log.v("meh", "Move Complete. Setting timeToMove_ to false");
                timeToMove_ = false;
                Log.v("meh", "timeToMove_ is now false");
            }
        }
    }
}


// Called by a different thread so that this thread knows when to make a move
public void move()
{
    Log.v("meh", "awaiting movementMutex in move()");
    // Synchronizing so that timeToMove_ doesn't get set true while in the middle of moving and thus setting it back false prematurely
    synchronized(movementMutex_)
    {
        Log.v("meh", "move called, setting timeToMove_");
        timeToMove_ = true;
        Log.v("meh", "timeToMove_ is now true");
    }
}

ログの印刷物を見ると、予期しない順序で印刷されているのがわかります。太字のステートメントは、同期の理解から、太字ではないプリントアウトでは解釈できないはずですが、そうではなく、回避しようとしていること自体が発生しています。次の動きを設定したために欠落しています。それがまだ真であり、すぐにそれを偽にしたときに真。

 08-12 10:47:19.860: V/meh(27639): awaiting movementMutex in move()  
 08-12 10:47:19.985: V/meh(27639): move called, setting timeToMove_  
 08-12 10:47:19.985: V/meh(27639): timeToMove_ is now true  
 08-12 10:47:19.985: V/meh(27639): **timeToMove_ was true, moving**  
 08-12 10:47:20.352: V/meh(27639): awaiting movementMutex in move()  

この次の行は不可能なはずです。それはmovementMutexを待っていません!

08-12 10:47:20.352: V/meh(27639): move called, setting timeToMove_  
08-12 10:47:20.360: V/meh(27639): timeToMove_ is now true  
08-12 10:47:20.360: V/meh(27639): **Move Complete. Setting timeToMove_ to false**  
08-12 10:47:20.360: V/meh(27639): **timeToMove_ is now false**  
4

1 に答える 1

1

質問へのコメントで述べたように、スレッドはそれ自体の同期ロックに再び入ることができます。「makeMove()」関数呼び出しは、実際には「move()」を呼び出すための扇動者でした。つまり、同じスレッドで実行されていたため、ロックアウトされていませんでした。つまり、以下のコードはデッドロックを引き起こしません。それは問題なく実行され、これは私が経験していたことです。

synchronized(movementMutex_)
{
    synchronized(movementMutex_)
    {
        doSomething();
    }
}
于 2012-08-14T16:35:24.533 に答える