Si varios hilos pueden compartir atributos, puede ser necesario sincronizarlos.
La sincronización, garantiza que a un objeto concreto, solo puede ser accedido por un hilo. En un momento determinado
Podemos sincronizar métodos declarándolos synchronized
- En un momento determinado, solo puede estar corriendo un método synchronized
Veamos este ejercicio en donde la clase Runnable comparte un contador estático, por lo que todas las instancias tienen la misma información. La clase da 10 vueltas, imprimiendo el contador y sumando uno
Y su Main
El resultado será:
Como habíamos comprobado antes, el orden de ejecución de los hilos es aleatorio, y a veces, uno puede incluso dar dos vueltas, pero el otro también interfiere, por eso los números aparecen duplicados.
Veamos qué pasa si utilizamos clases sincronizadas, para ello nuestra Runnable es
Y nuestra nueva Main
Lo que hemos hecho en la clase Sincro, es declarar un bloque de instrucciones, de la 13 a la 23 como sincronizadas, por lo que, hasta que no acaben, no se podrá acceder al objeto “n”
Esto hace que ahora la salida sea
En donde se han ejecutado las 10 vueltas de un hilo, y luego, se han ejecutado las 10 del otro
Las cosas están más claras, pero…uno de los hilos ha tenido que esperar a que el otro terminara. Si nuestro problema está únicamente en el comportamiento del contador, podemos sincronizar únicamente la impresión y modificaciones de ese contador
Modificamos Sincro
Y en la nueva salida veremos que el otro hilo, solo ha tenido que esperar que se imprimiera y modificara la variable, y después, ya ha podido entrar él, para hacer lo mismo. La salida será: