Seguridad de subprocesos, otras características básicas de la palabra clave sincronizada (bloqueo reentrante)


Resumió algunas de las características de sincronizado, las deficiencias esperan señalar.

Las características básicas de sincronizado:

1, reentrada de bloqueo sincronizado
Explicación: Reentrante, literalmente, este bloqueo se puede adquirir dos veces. Es decir, cuando un subproceso adquiere el bloqueo del objeto A, luego, durante la ejecución de su código (el bloqueo del objeto A no se libera), puede solicitar el bloqueo del objeto A nuevamente, y puede obtener el bloqueo del objeto A nuevamente, en lugar de tener un problema de punto muerto. La palabra clave sincronizada tiene esta característica y es un bloqueo reentrante.
El código es el siguiente:
public class SynchronizedDemo {

    public synchronized void method1(){
        System.out.println("method1");
        mothed2();
    }
    public synchronized  void method2(){
        System.out.println("method2");
    }

    public static void main(String...args){
        final SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedDemo.method1();
            }
        }).start();
    }
}

Resultado de salida:
Método 1;
método2 ;
Se puede ver en la salida que el hilo creado adquirió el bloqueo del objeto sincronizado Demo dos veces, verificando que sincronizado es un bloqueo reentrante.
¿Cuál es el significado de introducir bloqueos reentrantes?
Puede adquirir su propio bloqueo interno. Esto evita un punto muerto cuando el mismo bloqueo de objeto se llama por segunda vez.
En el desarrollo real, la modificación del pedido y la verificación del pedido (verificación del inventario, etc.) deben agregarse con bloqueos sincronizados; cuando realiza modificaciones del pedido, primero debe hacer la verificación del pedido (obtener el bloqueo del objeto del pedido dos veces) para que el bloqueo reentrante . Espera

Otras propiedades de la herencia reentrante de cerraduras-padre-hijo
El código es el siguiente:
public class SynchronizedDome1 {
    public synchronized void method1()  {
            System.out.println("method1");
    }
    static class SynchronizedDemo2 extends SynchronizedDome1{
        public synchronized void method2() {
                System.out.println("method2");
                method1();
        }
    }
    public static void main(String...args){
        final SynchronizedDemo2 synchronizedDemo2 = new SynchronizedDemo2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo2.method2();
            }
        }).start();
    }

}
Resultado de salida:
método2 ;
Método 1;
Significa que puede volver a ingresar el bloqueo del objeto primario después de adquirir el bloqueo del objeto secundario.
2. Después de que ocurra una excepción, el bloqueo se libera automáticamente.
El código es el siguiente:
public class SynchronizedDome2 {
    public int i = 10;
    public String str;
    public synchronized void method1()  {
            for(;i>0;i--){
               System.out.println("i:"+i);
              if(i==3){
                 str.toCharArray();
              }
            }
    }
    public static void main(String...args){
        final SynchronizedDemo2 synchronizedDemo2 = new SynchronizedDemo2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo2.method1();
            }
        }).start();
    }
}
Resultado de salida:
yo: 9
yo: 8
yo: 7
yo: 6
yo: 5
yo: 4
yo: 3
java.lang.NullPointerException
en thread.SynchronizedDome2.method1 (SynchronizedDome2.java:10)
en thread.SynchronizedDome2 $ 1.run (SynchronizedDome2.java:19)
en java.lang.Thread.run (Thread.java:745)
Indica que cuando ocurre una excepción, el programa no continúa ejecutándose y se libera el bloqueo del objeto.
3. Use el objeto como oyente.
public class SynchronizedDome3 {
    public String str = "lock";
    public void method1()  {
       synchronized (str){   
       System.out.println("当前线程名:"+Thread.currentThread().getName());
            }
    }
    public static void main(String...args){
        final SynchronizedDemo3 synchronizedDemo3 = new SynchronizedDemo3();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo3.method1();
            }
        },"name1").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                    synchronizedDemo3.method1();
            }
        },"name2").start();
    }
}
当前线程名:name2
当前线程名:name1
或者
当前线程名:name1
当前线程名:name2
说明: 选取任意对象作为锁
4,单例模式---双重校验锁(懒汉式)
public class SingleCase {
 private static SingleCase instance2;

public static SingleCase getInstance2(){
    if(instance2 == null){
        synchronized(SingleCase.lass){
            if(instance2 == null){
                instance2 = new SingleCase();
            }
        }
    }
    return instance2;
}
}



发布了26 篇原创文章 · 获赞 0 · 访问量 9935

Supongo que te gusta

Origin blog.csdn.net/weixin_38246518/article/details/78726530
Recomendado
Clasificación