Bloqueo de nivel de clase en Java

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. El bloqueo de nivel de clase evita que múltiples subprocesos ingresen un bloque sincronizado en cualquiera de todas las instancias disponibles de la clase en tiempo de ejecución. Esto significa que si en tiempo de ejecución hay 10 instancias de una clase, solo un subproceso podrá acceder a un solo método o bloque de cualquier instancia a la vez. Se utiliza si desea proteger los datos estáticos.

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.

Métodos: Thread puede adquirir el bloqueo a nivel de clase mediante dos métodos, a saber

  1. Utilizando el método estático sincronizado.
  2. Uso de bloque sincronizado.

Método 1: Usar el método estático sincronizado

Implementación: Tenemos una clase Geek. Queremos usar el método de sincronización estática de esta clase, tan pronto como el subproceso ingresó al método sincronizado, el subproceso adquiere el bloqueo a nivel de clase, el resto de los subprocesos esperan para obtener el bloqueo del monitor de clase. El subproceso dejará un bloqueo cuando salga del método sincronizado.

public static synchronized int incrementCount()
{
}

Ejemplo

Java

// Java program to illustrate class level lock
 
// Main Class
// Implememnting the Runnable interface
class Geek implements Runnable {
 
    // Method 1
    // @Override
    public void run() { Lock(); }
 
    // Method 2
    // Method is static
    public static synchronized void Lock()
    {
        // Gwetting the name of current thread by using
        // getName() method to get name of the thread and
        // currentThread() to get the current thread
        System.out.println(
            Thread.currentThread().getName());
 
        // class level lock
        synchronized (Geek.class)
        {
            System.out.println(
                "in block "
                + Thread.currentThread().getName());
            System.out.println(
                "in block "
                + Thread.currentThread().getName()
                + " end");
        }
    }
 
    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
        // Creating an object of above class
        // in the main() method
        Geek g1 = new Geek();
 
        // Sharing the same object across two Threads
 
        // Creating an object of thread class where
        // t1 takes g1
        Thread t1 = new Thread(g1);
 
        // Creating an object of thread class where
        // t2 takes g1
        Thread t2 = new Thread(g1);
 
        // Creating second object of above class
        // in the main() method
        Geek g2 = new Geek();
 
        // Creating an object of thread class where
        // t3 takes g2
        Thread t3 = new Thread(g2);
 
        // setName() method is used to set name to the
        // thread
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
 
        // start() method is used for initiating the current
        // thread
        t1.start();
        t2.start();
        t3.start();
    }
}
Producción

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

Explicación de salida: 

El subproceso t1 ingresó al método estático sincronizado y mantuvo un bloqueo en la clase de Geek. Entonces, el resto de los subprocesos esperaron a que Thread t1 liberara el bloqueo en la clase de Geek para que pudiera ingresar al método sincronizado estático.

Método 2: Usar el método de bloque sincronizado 

Implementación: Tenemos una clase «Geek». Queremos crear un bloque de sincronización y pasar el nombre de la clase. class como parámetro indica qué clase debe sincronizarse en el nivel de clase. Tan pronto como el subproceso ingresó al bloque sincronizado, el subproceso adquiere el bloqueo en la clase, el resto de los subprocesos esperan para obtener el bloqueo del monitor de clase. El hilo dejará el bloqueo cuando salga del bloque sincronizado.

synchronized (Geek.class) {
    //thread has acquired lock on  Geek class
}

Ejemplo

Java

// Java program to illustrate class level lock
 
// Main Class
// It is implementing the Runnable interface
class Geek implements Runnable {
 
    // Method 1
    // @Override
    public void run()
    {
        // Acquire lock on .class reference
        synchronized (Geek.class)
 
        // ClassName is name of the class containing method.
        {
            {
                System.out.println(
                    Thread.currentThread().getName());
 
                System.out.println(
                    "in block "
                    + Thread.currentThread().getName());
                System.out.println(
                    "in block "
                    + Thread.currentThread().getName()
                    + " end");
            }
        }
 
        // Method 2
        // Main driver method
        public static void main(String[] args)
        {
            // Creating an object of above class
            // in the main() method
            Geek g1 = new Geek();
 
            // Creating an object of thread class i.e Thread
            // 1 where t1 takes g1 object
            Thread t1 = new Thread(g1);
            // Here, creating Thread 2 where t2 takes g1
            // object
            Thread t2 = new Thread(g1);
 
            // Creating another object of above class
            // in the main() method
            Geek g2 = new Geek();
           
            // Now Creating Thread 3 where t3 takes g2 object
            Thread t3 = new Thread(g2);
 
            // Ginving custom names to above 3 threads
            // using the setName() method
            t1.setName("t1");
            t2.setName("t2");
            t3.setName("t3");
 
            // start() method is used to begin execution of
            // threads
            t1.start();
            t2.start();
            t3.start();
        }
    }

Producción:

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

Explicación de salida: 

El subproceso t1 ingresó al bloque sincronizado y estaba manteniendo el bloqueo en la clase ‘Geek’. Entonces, el resto de los subprocesos esperaron a que Thread t1 liberara el bloqueo en la clase ‘Geek’ para que pudiera ingresar al bloque sincronizado.

Publicación traducida automáticamente

Artículo escrito por aksrathod07 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 *