Nivel de objeto y bloqueos de nivel de clase en Java

Sincronización: 

La sincronización es un modificador que se usa solo para el método y los bloques. Con la ayuda de un modificador sincronizado, podemos restringir el acceso a un recurso compartido solo por un hilo. Cuando dos o más subprocesos necesitan acceso a los recursos compartidos, hay alguna pérdida de datos, es decir, inconsistencia de datos. El proceso mediante el cual podemos lograr la consistencia de los datos entre varios subprocesos se denomina Sincronización.

¿Por qué necesita sincronización? 

Supongamos que tiene dos subprocesos que leen y escriben en el mismo ‘recurso’. Supongamos que hay una variable llamada geek, y desea que en un momento solo un subproceso acceda a la variable (forma atómica). Pero sin la palabra clave sincronizada, es posible que su hilo 1 no vea los cambios que el hilo 2 hizo a geek, o peor aún, puede que solo haya cambiado la mitad que causa el problema de inconsistencia de datos. Esto no sería lo que lógicamente esperas. La herramienta necesaria para evitar estos errores es la sincronización.

En la sincronización, hay dos tipos de bloqueos en los subprocesos:  

  • Bloqueo a nivel de objeto: cada objeto en Java tiene un bloqueo único. Siempre que estemos usando una palabra clave sincronizada, solo el concepto de bloqueo aparecerá en la imagen. Si un subproceso quiere ejecutar el método sincronizado en el objeto dado. Primero, tiene que obtener un bloqueo en ese objeto. Una vez que el subproceso obtuvo el bloqueo, se le permite ejecutar cualquier método sincronizado en ese objeto. Una vez que se completa la ejecución del método, el subproceso libera automáticamente el bloqueo. JVM se encarga de adquirir y liberar el bloqueo internamente y el programador no es responsable de estas actividades. Echemos un vistazo al siguiente programa para comprender el bloqueo de nivel de objeto:

JAVA

// Java program to illustrate
// Object lock concept
class Geek implements Runnable {
    public void run() { Lock(); }
    public void Lock()
    {
        System.out.println(
            Thread.currentThread().getName());
        synchronized (this)
        {
            System.out.println(
                "in block "
                + Thread.currentThread().getName());
            System.out.println(
                "in block "
                + Thread.currentThread().getName()
                + " end");
        }
    }
 
    public static void main(String[] args)
    {
        Geek g = new Geek();
        Thread t1 = new Thread(g);
        Thread t2 = new Thread(g);
        Geek g1 = new Geek();
        Thread t3 = new Thread(g1);
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
        t1.start();
        t2.start();
        t3.start();
    }
}
Producción

t1
t3
t2
in block t3
in block t1
in block t3 end
in block t1 end
in block t2
in block t2 end
  • Bloqueo de nivel de clase: cada clase en Java tiene un bloqueo único que no es más que un bloqueo de nivel de clase. Si un subproceso desea ejecutar un método sincronizado estático, entonces el subproceso requiere un bloqueo de nivel de clase. Una vez que un subproceso obtuvo el bloqueo de nivel de clase, se le permite ejecutar cualquier método sincronizado estático de esa clase. Una vez que se completa la ejecución del método, el subproceso libera automáticamente el bloqueo. Veamos el siguiente programa para una mejor comprensión:

JAVA

// Java program to illustrate class level lock
class Geek implements Runnable {
    public void run() { Lock(); }
 
    public void Lock()
    {
        System.out.println(
            Thread.currentThread().getName());
        synchronized (Geek.class)
        {
            System.out.println(
                "in block "
                + Thread.currentThread().getName());
            System.out.println(
                "in block "
                + Thread.currentThread().getName()
                + " end");
        }
    }
 
    public static void main(String[] args)
    {
        Geek g1 = new Geek();
        Thread t1 = new Thread(g1);
        Thread t2 = new Thread(g1);
        Geek g2 = new Geek();
        Thread t3 = new Thread(g2);
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
        t1.start();
        t2.start();
        t3.start();
    }
}
Producción

t1
t2
t3
in block t1
in block t1 end
in block t3
in block t3 end
in block t2
in block t2 end

Referencia: https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
 

Este artículo es una contribución de Bishal Kumar Dubey . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *