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
- Utilizando el método estático sincronizado.
- 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(); } }
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