Kotlin, problema de condición de carrera

Código relevante aquí

Básicamente, tenemos dos hilos, uno encabezando el renderizado que sigue llamando a display() y otro que se encarga de las inputs del usuario, llamando al mouse o evento key correspondiente según corresponda.

Viewpole y polos de object no son nada más que classs de ayuda para facilitar el event handling la matriz con respecto a la camera y el object (s).

Sus methods se llaman tanto desde la display() como desde los methods de input del usuario.

display() llama a viewpole.calcMatrix() y objectpole.calcMatrix() mientras que el hilo de input los llama indirectamente, por ejemplo basicLighting.mouseDragged() -> objectpole.mouseDragged() -> rotateView() -> calcMatrix()

La condición de carrera comenzó a aparecer cuando comencé a usar objects de grupo para networkingucir la presión del GC en escenarios específicos. Revisé decenas de veces, cada object se usa solo una vez (excepto when ).

Detecto la condición de carrera imprimiendo la matriz de vista en cada llamada de display() . Cada vez que es diferente, significa que tengo uno. Un ejemplo aquí .

Investigando, descubrí usando println simple, por ejemplo, que el Viewpole.calcMatrix() veces se llamaba antes de que otra llamada haya terminado para ejecutarlo por completo.

Agregar @Synchronized en cada calcMatrix() (viewpole y objectpole) lo networkingujo mucho, diría 80/90%.

Pero aun así, algunas veces, experimento condiciones de carrera. Traté de synchronize(lock){} también cada llamada desde el hilo de input del usuario, como aquí :

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

No ayudó.

¿Qué estoy haciendo mal? ¿Y cuál es la forma correcta de implementar la synchronization para mi caso? Es decir, dos hilos llamando a la misma class.

    Los problemas de enhebrado nunca se tratan de hilos que llamen a las mismas classs. Se trata de compartir estado mutable entre hilos. Como puedo ver, su estado compartido son las matrices.

    Lo que estás haciendo mal es difícil de decir sin revisar todo tu código. Pero aquí hay algunos consejos: / viewPole.calcMatrix () devuelve una reference a mat4_B. En display (), esta reference se usa fuera del bloque sincronizado. Por lo tanto, mat4_B podría modificarse simultáneamente mientras se usa en display () / viewPole.calcMatrix () y objectPole.calcMatrix () en bloques sincronizados por separado. Entonces, la matriz viewPole podría estar basada en un estado diferente a la matriz objectPole. No puedo decir si esto es un problema para su caso de uso.

    El enfoque debería ser: / networkingucir el estado compartido tanto como sea posible (es decir, pasando copys) / recuperar todos los datos en una sola operación atómica (sincronizada)