Sobes.tech
Middle+

¿Cómo funciona el mecanismo de sincronización 'synchronized' en Java en el fondo?

sobes.tech AI

Respuesta de la IA

El mecanismo synchronized en Java se basa en la concept de monitores (objetos monitor). A cada objeto en Java se le asocia un monitor.

Cuando un hilo entra en un bloque o método sincronizado, intenta adquirir el monitor del objeto correspondiente. Si el monitor está libre, el hilo lo adquiere y continúa con la ejecución. Si el monitor está ocupado por otro hilo, el hilo actual se bloquea y pasa a un estado de espera hasta que el monitor se libere.

Cuando un hilo sale de un bloque o método sincronizado (ya sea finalizándolo con éxito o lanzando una excepción), libera el monitor.

Dentro del monitor se implementan:

  1. Exclusión mutua (Mutual Exclusion): Solo un hilo puede poseer el monitor de un objeto en un momento dado. Esto garantiza que solo un hilo pueda ejecutar código sincronizado para ese objeto.
  2. Espera y notificación (Waiting and Notification): El monitor incluye un conjunto de métodos relacionados wait(), notify() y notifyAll(). Estos métodos permiten a los hilos que poseen el monitor liberarlo temporalmente y pasar a un estado de espera, y luego ser notificados por otros hilos sobre la posibilidad de continuar.

La implementación a bajo nivel incluye:

  • Instrucción monitorenter: Se ejecuta al entrar en un bloque o método sincronizado. Intenta adquirir el monitor del objeto.
  • Instrucción monitorexit: Se ejecuta al salir de un bloque o método sincronizado (ya sea por finalización normal o por excepción). Libera el monitor del objeto.

Estas instrucciones forman parte del código byte de Java y son gestionadas por la máquina virtual Java (JVM). La JVM utiliza mecanismos nativos del sistema operativo (como mutexes, semáforos) para gestionar los monitores y el bloqueo/desbloqueo de hilos.

La adquisición del monitor puede ser implementada a nivel de objeto (para métodos y bloques de instancia) o a nivel de clase (para métodos y bloques estáticos), usando el objeto Class como bloqueo.

Ejemplo de uso:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Método sincronizado
        count++;
    }

    public void decrement() {
        synchronized (this) { // Bloque sincronizado
            count--;
        }
    }

    public static synchronized void staticMethod() { // Método estático sincronizado
        // ...
    }
}

Tabla de métodos de la clase Object relacionados con monitores:

Método Descripción
wait() El hilo que posee el monitor libera temporalmente el monitor y pasa a estado de espera.
notify() Notifica a uno de los hilos en espera que puede intentar adquirir el monitor y continuar.
notifyAll() Notifica a todos los hilos en espera.