2017-03-23 34 views
0

相關代碼here科特林,競爭條件問題

從本質上講,我們有兩個線程,一個領導,保持呼叫display()和另外一個,大約需要用戶輸入照顧渲染,調用相應的mouse or key event相應

Viewpoleobject極點不是別的幫助類,以便於相機和對象的矩陣處理。

他們的方法都是從display()和用戶輸入法調用的。

display()同時呼籲viewpole.calcMatrix()objectpole.calcMatrix()而輸入線程調用他們間接地,例如basicLighting.mouseDragged() - >objectpole.mouseDragged() - >rotateView() - >calcMatrix()

競爭狀態開始流行起來,當我開始使用pool objects減少GC在特定情況下的壓力。我查了幾十次,每個對象只用了一次(除了用when)。

我通過打印出view matrix每個display()調用來檢測競爭狀態。每當它不同時,就意味着我得到了一個。示例here

調查中,我發現使用簡單的println,例如,Viewpole.calcMatrix()有時會在另一個調用完成之前被調用以完全執行它。

calcMatrix()(viewpole和objectpole)上加上@Synchronized減少了很多,我說80/90%。

但是,有時候,我還是經歷了比賽條件。我試圖synchronize(lock){}還每個電話用戶輸入的線程,就像here

val lock = Any() 

override fun mousePressed(e: MouseEvent) { 
    synchronized(lock) { 
     viewPole.mousePressed(e) 
     objectPole.mousePressed(e) 
    } 
} 

它並沒有幫助。

我在做什麼錯?什麼是正確的方式來實現我的情況下的同步?也就是說,兩個線程調用同一個類。

回答

1

線程問題永遠不會是調用相同類的線程。它是關於線程之間共享可變狀態的。 正如我所見,您的共享狀態是矩陣。

你在做什麼錯誤很難說,沒有審查你的整個代碼。但是這裏有一些提示: /viewPole.calcMatrix()返回對mat4_B的引用。 在display()中,此引用將在synchronized塊之外使用。因此,mat4_B可能會在display()使用時被同時修改。() /viewPole.calcMatrix()和objectPole.calcMatrix()在單獨的同步塊中調用。所以viewPole矩陣可能基於與objectPole矩陣不同的狀態。我無法分辨這是否是您的使用案例的問題。

該方法應當是: /減少共享狀態儘可能(即通過使拷貝) /提取在一個單一的,原子(同步)操作的所有數據