Modificador synchronized en Java

Hola a todos, hoy os voy a explicar como se utiliza el modificador synchronized y como funciona en Java.

El modificador synchronized en Java nos permite que un hilo entre de forma sincronizada en un método/función, ¿qué significa exactamente? Quiere decir que cuando un hilo o proceso ejecute ese método/función, ningún otro podrá acceder hasta que el primero acabe.

La utilidad de que un método/función se utiliza para controlar el acceso de multiples hilos a un recurso compartido.

Veamos un ejemplo práctico para ver su funcionamiento.

Lo primero, vamos a crear una clase llamado Counter que tendrá dos métodos, uno con el modificador synchronized y otro sin este. El método en sí lo que hará es mostrar de 0 a n.

Le pondremos un atributo sincronizado para llamar a un método u otro según queramos.

public class Counter {
    
    private boolean sincronizado;

    public Counter(boolean sincronizado) {
        this.sincronizado = sincronizado;
    }

    public boolean isSincronizado() {
        return sincronizado;
    }
    
    public synchronized void mostrarNumerosSincronizado(int id, int n) {
        System.out.println("Inicio hilo " + id);
        for (int i = 0; i <= n; i++) {
            System.out.println(i);
        }
        System.out.println("Fin Hilo " + id);
    }

    public void mostrarNumerosNoSincronizado(int id, int n) {
        System.out.println("Inicio hilo " + id);
        for (int i = 0; i <= n; i++) {
            System.out.println(i);
        }
        System.out.println("Fin hilo " + id);
    }

}

Ahora, crearemos una clase HiloContador que herede de Thread. Tendrá como atributos un id para identificar el hilo, un numero que indica hasta dónde debe mostrar por pantalla y una instancia de la clase Counter.

public class HiloContador extends Thread {

    private int id;
    private Counter counter;
    private int n;

    public HiloContador(int id, int n, Counter counter) {
        this.id = id;
        this.n = n;
        this.counter = counter;
    }

    public void run() {
        if (this.counter.isSincronizado()) {
            this.counter.mostrarNumerosSincronizado(this.id, this.n);
        } else {
            this.counter.mostrarNumerosNoSincronizado(this.id, this.n);
        }
    }

}

En la clase Principal, vamos a crear nuestros hilos y ejecutarlos.

public class Principal {

    public static void main(String[] args) {

        try {
            boolean sincronizado = false;
            
            Counter c = new Counter(sincronizado);
            HiloContador h1 = new HiloContador(1, 10, c);
            HiloContador h2 = new HiloContador(2,  5, c);
            
            h1.start();
            h2.start();
            
            h1.join();
            h2.join();
            
            System.out.println("Fin del programa");
        } catch (InterruptedException ex) { }
       
    }   
}

Vamos a ejecutarlo de las dos formas.

  • No sincronizado:

  • Sincronizado:

¿Ves la diferencia? En el primer caso ambos empiezan a la vez, es decir, entran en el método a la vez. En el segundo caso, cuando uno entra el otro espera hasta que el otro termine, por lo que no se solapan.

Te dejo un video donde explico todo el proceso.

Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.

Compartir

Deja una respuesta

Tu dirección de correo electrónico no será publicada.