2013-01-08 47 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:是的,這正是問題所在:-) –