2012-08-12 144 views
2

​​不会出现如我所预料的工作。它不应该使括号内的代码原子相对于同一个对象的一个​​单独的代码块​​?同步不同步

我发现它不同步所有我的代码中。

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() 

这下一行应该是不可能的。它不等待运动Mutex!

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** 
+1

makeMove()函数是否调用move()函数?即,两个同步块是由同一个线程访问的?这将解释你所看到的。 – mah 2012-08-12 15:41:34

+0

你是说嵌套同步调用不会导致死锁,而是会通过,因为它已经有访问权限?它不等同于一个互斥体的“wait()”调用吗?如果是这样,代码进度可能会导致它间接调用它自己。如果这是正确的,随时回答,我会标记它的答案。 – CodeMonkey 2012-08-12 15:52:24

+0

虽然很难找到有关嵌套同步调用的文档,但是一个简单的测试表明它确实忽略了它。它不会导致死锁。所以我很确定这是我的问题。谢谢!对锁重入(嵌套调用Sych发表) – CodeMonkey 2012-08-12 16:02:07

回答

1

正如在问题的评论中提到的,一个线程能够重新输入自己的同步锁。 “makeMove()”函数调用实际上是调用“move()”的煽动者,这意味着它正在同一线程下执行,因此不会被锁定。总之,下面的代码不会导致死锁;它会执行没有问题,这是我所经历的。

synchronized(movementMutex_) 
{ 
    synchronized(movementMutex_) 
    { 
     doSomething(); 
    } 
}