Kotlin,竞争条件问题

时间:2017-03-23 09:34:15

标签: synchronization kotlin

相关代码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()有时在另一个调用完成之前被调用以完全执行它。

在每个@Synchronized(viewpole和objectpole)上添加calcMatrix()减少了很多,我说80/90%。

但是,有时候,我会遇到竞争状况。我也尝试synchronize(lock){}来自用户输入线程的每个调用,例如here

val lock = Any()

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

它没有帮助。

我做错了什么?那么为我的案例实现同步的正确方法是什么?也就是说,两个线程调用同一个类。

1 个答案:

答案 0 :(得分:1)

线程问题绝不是关于调用相同类的线程。它是关于在线程之间共享可变状态。 我可以看到,你的共享状态就是矩阵。

如果不审查整个代码,很难说你做错了什么。但这里有一些提示: / viewPole.calcMatrix()返回对mat4_B的引用。 在display()中,此引用随后在synchronized块之外使用。因此mat4_B可能会在display()使用时同时修改 / viewPole.calcMatrix()和objectPole.calcMatrix()在单独的同步块中调用。因此viewPole矩阵可能基于与objectPole矩阵不同的状态。我不知道这是否是您的用例的问题。

方法应该是: /尽可能减少共享状态(即通过传递副本) /在单个原子(同步)操作中获取所有数据