Estoy aprendiendo programación simultánea en Java y estoy escribiendo una simulación para Game of Life.Programa Java multiproceso para el juego de la vida de Conway: contención en las celdas fronterizas
Aquí es lo que estoy pensando:
- Uso int [] [] para almacenar los estados de las células
- partición del int [] [] en segmentos T y el uso de subprocesos de trabajo t
- Los subprocesos t leerán de su segmento, calcularán nuevos valores para todas las celdas de su segmento y actualizarán las celdas.
- Una vez que terminaron el cálculo esperan en una barrera para que otros trabajadores terminen
- cuando se cruza la barrera, el hilo principal actualizará la IU.
- los trabajadores proceden a calcular el siguiente estado.
Ahora habrá contención en los bordes comunes de los segmentos. Si un hilo sobrescribió el estado de una celda de borde antes de que su vecino haya leído el valor anterior, el cálculo del vecino será incorrecto.
¿Cuáles son mis opciones?
- Uso exigible en lugar de ejecutable y haga que los subprocesos de trabajo devuelven el nuevo valor (en lugar de actualizar los mismos segmentos). El hilo principal puede actualizar la matriz después de cruzar la barrera. Esta opción implica copiar los resultados devueltos por subprocesos de trabajo en la matriz.
- Utilice dos barreras. El hilo de los trabajadores hace una copia de las celdas de los bordes de los segmentos de sus vecinos y espera en la primera barrera. Una vez que se pasa esta barrera, proceden a calcular los próximos estados y actualizar los segmentos en su lugar. Luego esperan en la 2da barrera. el hilo principal actualiza la interfaz de usuario.
Mi pregunta es, ¿hay alguna otra manera de hacer frente a la contención en las células del borde que no implica copiar datos o es más eficiente que las dos opciones anteriores? ¿Puede estar utilizando ReaderWriterLock, variable volátil u otro mecanismo de sincronización?
ACTUALIZACIÓN: Hasta ahora, el double buffering solution by Peter es el más limpio. Pero tengo una pregunta. Como las dos matrices son datos compartidos y no estamos utilizando ninguna sincronización (acceso sincronizado o variable volátil), ¿no creará el problema de visibilidad? ¿Podrían varias CPU almacenar en caché los valores de la matriz y actualizar solo una parte de la matriz con cada iteración? Entonces los hilos obtendrán valores obsoletos para las celdas de borde. es posible? Si no, por qué. Si es así, ¿cómo lo resuelvo? Parece declaring two arrays volatile will not make their individual elements volatile.
algo a considerar es usar AtomicInt en lugar de regular int –
¿Ventaja? ¿No será eso una sincronización excesiva? – Helen
¿Por qué necesita usar int? ¿No sería más lógico y eficiente almacenar usando booleanos? – Pool