2013-01-08 46 views
1

注意:我不在寻找解决方法;如果有必要,我相信我可以找到其他方法。我只是觉得我错过了一些基本或古怪的东西,我想知道我错过了什么。或者,如果有一种方法可以使用调试器来获取更多的信息,那也不错。谢谢!同步未输入

我遇到了使用同步的问题。我收到了僵局,但似乎完全不可能。我已经在每次同步调用之前放置了打印语句,就在每次调用之前,并且在退出之前,我可以看到谁拥有哪些同步对象。我发现它不会进入我的一个同步调用中,即使当前没有人持有该对象上的锁。是否有某种我错过的或者非法嵌套操作的怪癖?这是我正在做的事情。

噢,和最奇怪的事情是,去掉两个 “busyFlagObject” 同步使得它做工精细...

主题1:

public void DrawFunction() 
{ 
    synchronized(drawObject) 
    { 
     ... 
     // Hangs here though nobody has a lock on this object 
     synchronized(animationObject) 
     { 

     } 
    } 
} 

线程2:

public void AnotherFunction() 
{ 
    synchronized(busyFlagObject) 
    { 
     // Calls a function that also uses this same Synchronized call 
     synchronized(busyFlagObject) 
     { 
      // Calls another function that uses another Synchronized call 
      // Hangs here waiting for the draw function to complete which it SHOULD 
      // be able to do no problem. 
      synchronized(drawObject) 
      { 

      } 

      // Never gets to this one assuming the Log statements don't 
      // buffer and aren't flushed but still shouldn't be a problem anyway. 
      synchronized(animationObject) 
      { 

      } 
     } 
    } 
} 
+0

如果删除嵌套的'busyFlagObject'同步化之一会发生什么? – Archer

+0

您确定问题出在您的同步块中,而不是您从其调用的函数中?您是否尝试删除线程同步和日志以外的所有内容? – Leonidos

+0

只删除一个busyFlagObject仍然会导致相同的死锁。我没有尝试删除函数中的代码,但它只是我已经显示的那么深。没有显示的东西只是数学运算或变量设置。我知道它挂在同步调用上,因为调试器显示两个线程停留在它们上面。 – CodeMonkey

回答

2

在调试器下运行您的应用程序或使用JDK工具中的“jstack”。这将直接向您显示哪些线程等待锁定和哪些锁定,因此我们不必猜测问题出在哪里:-)

这就是说,你提到你同步布尔。请记住,该类仅用于两个实例,许多事情(特别是装箱)将隐式地将布尔实例更改为“共享”值。你确定你的锁定对象不是同一个实例吗?您可以考虑使用new Object()作为您的显示器对象。

值得注意的是,这个isn't the only place that this can happen在Java Concurrency in Practice中有一个很好的入口,特别是string interning,我目前还找不到链接。不要使用不受您控制的类型,因为它不打算执行以下操作:-)

+0

我没有使用调试器,发现我的两个线程死锁的地方。一个在animationObject上死锁,另一个在drawObject上死锁。被锁定在animationObject上的对象确实包含drawObject,但另一个不包含animationObject,因此应该没有死锁。如果有一种方法可以看到谁“持有锁”,那将是很好的,但我不知道如何看到线程锁定的位置。我不确定我是否完全理解你对布尔的含义,但我会尝试新的Object()并查看它是否有所作为。谢谢! – CodeMonkey

+0

哦!我想我明白你现在在说什么。那么“private Boolean bawb = true”与“private Boolean phred = true”是同一个实例,并且如果其中一个是假的,它们只会彼此不同?这肯定会解决问题! – CodeMonkey

+0

@CodeMonkey:是的,这正是问题所在:-) –