Mecanismo de bloqueo sincronizado-java

Synchronized es un bloqueo atómico incorporado, que está escrito en C ++. No podemos ver el código fuente en su interior. Es un conjunto de instrucciones. Podemos usar esta instrucción para implementar operaciones de bloqueo en objetos.

Sintaxis: (1) Bloque de código de sincronización; (2) Método de sincronización .

Mecanismo de bloqueo de objetos (monitor):
(1) Primero, observemos la operación de bloqueo de bloques de código sincronizados usando sincronizados;

package Synchronized;

public class SynchronizedTest {
    
    
    public static Object object=new Object();

    public static void main(String[] args) {
    
    
        synchronized (object){
    
    
            System.out.println("hello baby");
        }
    }
}

Después de desensamblar, podemos ver la información de codificación desensamblada:
Inserte la descripción de la imagen aquí
después de ejecutar el bloque de código sincronizado, la instrucción monitorenter debe ejecutarse primero, y la instrucción monitorexit al salir . Después del análisis, se puede ver que la clave para usar Synchronized para la sincronización es obtener el monitor monitor del objeto, una vez que el hilo obtiene el monitor, puede continuar ejecutándose, de lo contrario solo puede esperar. El proceso de adquisición es mutuamente excluyente, es decir, solo un hilo puede adquirir el monitor al mismo tiempo.

El código de bytes anterior contiene una instrucción monitorenter y dos instrucciones monitorexit, esto se debe a que la máquina virtual Java necesita asegurarse de que el bloqueo adquirido se pueda desbloquear tanto en la ruta de ejecución normal como en la ruta de ejecución anormal.

(2) Luego de ejecutar el bloqueo y compilación del bloque de código sincronizado:
Esta marca aparece en el archivo bytecode compilado: ACC_SYNCHRONIZED, que indica que al ingresar al método, la máquina virtual Java necesita realizar una operación de monitoreo y al salir del método En este momento, ya sea que esté regresando normalmente o lanzando una excepción a la persona que llama, la máquina virtual Java necesita realizar una operación de monitoreoxit. (Entonces hay dos operaciones de salida monitoreadas)

public class SynchronizedTest {
    
    
    public static Object object=new Object();
    public  synchronized void eat(){
    
    
        System.out.println("eat banana");
    }

    public static void main(String[] args) {
    
    
        SynchronizedTest s=new SynchronizedTest();
        s.eat();
        }
   }

El resultado compilado muestra:
Inserte la descripción de la imagen aquí

El papel del monitornter y monitorxit:

Podemos entender de manera abstracta que cada objeto de bloqueo tiene un contador de bloqueo y un puntero al hilo que sostiene el bloqueo.

Cuando se ejecuta el monitorizador, si el contador del objeto de bloqueo de destino es 0, significa que no está retenido por otros hilos. En este caso, la máquina virtual Java establece el subproceso de retención del objeto de bloqueo como el subproceso actual e incrementa su contador en 1. En el caso de que el contador del objeto de bloqueo de destino no sea 0, si el hilo que contiene el objeto de bloqueo es el hilo actual, la máquina virtual Java puede aumentar su contador en 1; de lo contrario, debe esperar hasta que el hilo de retención libere el bloqueo. .
Cuando se ejecuta monitorexit, la máquina virtual Java necesita disminuir el contador del objeto de bloqueo en 1. Cuando el contador desciende a 0, significa que se ha liberado el bloqueo.

La razón para usar este método de contador es permitir que el mismo hilo adquiera repetidamente el mismo bloqueo . Por ejemplo, si hay varios métodos sincronizados en una clase Java, las llamadas mutuas entre estos métodos, ya sea directa o indirectamente, implicarán operaciones de bloqueo repetidas en el mismo bloqueo. Por lo tanto, necesitamos diseñar tal característica reentrante para evitar restricciones implícitas en la programación.

Supongo que te gusta

Origin blog.csdn.net/m0_46551861/article/details/115168611
Recomendado
Clasificación