Skip to content

1 Introducción a la Sincronización

Introducción

Uno de los problemas más frecuentes cuando realizamos programación concurrente consiste en el hecho de que varios hilos compartan un recurso. Es bastante usual que distintos hilos deban leer y escribir sobre las mismas variables de datos o tener acceso al mismo fichero o conexión de base de datos. Estos recursos compartidos pueden provocar errores de acceso o de inconsistencia de datos, por lo que tendremos que implementar mecanismos que los eviten.

Para ayudar a los programadores a implementar secciones críticas, Java (y la mayoría de los lenguajes de programación) ofrecen distintos mecanismos de sincronización. En general, llamamos mecanismo de sincronización a la palabra reservada o clase que es usada para controlar el flujo de hilos cooperativos en base a su estado (ver).

Los distintos mecanismos de sincronización incorporan una o varias de las siguientes capacidades:

  • Visibilidad: Asegura que los cambios realizados por un hilo en un recurso compartido son visibles para el siguiente hilo que acceda a dicho recurso. Si no se cumpliera este requisito, los hilos podrían estar trabajando con valores inconsistentes para el recurso. La visibilidad no está implementada por defecto en los tipos primitivos de Java.
  • Exclusión mutua: Permite el acceso concurrente y la actuación de datos compartidos mutables sin producir race conditions. Para ello se implementa el concepto de sección crítica, que consiste en un bloque de código que accede a un recurso compartido y que no puede ser ejecutado a la vez por más de un hilo en un momento dado. Cuando un hilo quiere acceso a una sección crítica, usa el mecanismo de sincronización para averiguar si ya hay algún otro hilo ejecutándola. Si la sección crítica está disponible, el hilo entra en ella. Si, por el contrario, ya está ocupada, el hilo es suspendido por el mecanismo de sincronización hasta que el hilo que la está ocupando termine la ejecución de la sección crítica. Cuando haya más de un hilo esperando para poder ejecutar la misma sección crítica, la JVM elige uno de ellos, y el resto esperan su turno.
  • Coordinación: Asegura que el código se ejecuta en el orden correcto, en el momento correcto y bajo las condiciones necesarias.
  • Barrera de sincronización: Aseguro que varios hilos deben suspender su ejecución en un determinado punto de sincronización (barrera) hasta que todos los hilos hayan llegado a dicho punto.