Análisis del uso y escenarios de uso de la programación sincronizada.

El propósito de la vida es crecer, la esencia de la vida es el cambio, el desafío de la vida es conquistar
el propósito de la vida es crecer, la esencia de la vida es el cambio, el desafío de la vida es conquista


La palabra clave sincronizada es casi una pregunta obligatoria para cada entrevista. Hoy, hablemos sobre el uso de sincronizado y sus escenarios de uso.

Como todos sabemos, hay tres características principales en el modelo de memoria Java: atomicidad, visibilidad y orden.

sincronizado: garantiza visibilidad y atomicidad

En el modelo de memoria Java, sincronizado estipula que cuando un hilo está bloqueado, primero borra la memoria de trabajo-> copia la última copia variable de la memoria principal a la memoria de trabajo-> ejecuta el código-> cambia las variables compartidas El valor se actualiza en la memoria principal-> suelte el mutex

Ordenando: El orden natural en un programa Java se puede resumir en una oración. Si observa en este hilo, todas las operaciones se ordenan naturalmente, y si observa otro hilo en un hilo, todas las operaciones están fuera de orden. De

Sincronizado permite el acceso a variables o bloques de código por un solo hilo a la vez, lo que reduce el consumo de memoria. Lo que está bloqueado es una instancia de un objeto, una instancia que existe en el montón, no un bloque de código. Otros hilos deben esperar a que este objeto use Este objeto solo se puede obtener cuando se libera, por lo que el pensamiento sincronizado también se puede entender como un bloqueo pesimista

Y mire el modo singleton con bloqueo de verificación doble a continuación

     private volatile static Singleton singleton;

     public static Singleton getSingleton(){    
        if(null == singleton){        
           synchronized (Singleton.class) {            
              if(null == singleton){                
                   singleton = new Singleton();            
              }        
           }    
         }
         return singleton;
     }

     public static void main(String[] args) {    
       for(int i = 0;i<10;i++){        
          new Thread(new Runnable() {            
          @Override            
          public void run() {                
              System.out.println(Thread.currentThread().getName()+":"+Singleton.getSingleton().hashCode());            
          }}).start();    
     }复制代码


Como puede ver, el objeto Singleton se ha modificado con volátil, y se ha juzgado dos veces más. La visibilidad modificada se ha implementado con modificación volátil (volátil también es una palabra clave). Los dos juicios se deben a que el primer juicio fue El modo singleton solo necesita crear una instancia, y si se vuelve a llamar más tarde, volverá directamente a la instancia creada anteriormente, por lo que la mayoría de las veces, no es necesario ejecutar el código en el método de sincronización, lo que mejora enormemente el rendimiento. El segundo juicio es que se supone que después de que el subproceso 1 realiza la primera verificación, en este momento, el subproceso 2 también adquiere los derechos de ejecución de la CPU. A continuación, el subproceso 2 adquiere un bloqueo y crea una instancia. En este momento, el subproceso 1 obtiene la autoridad de ejecución y también crea una instancia. Como resultado, se crearán varias instancias , por lo que deberá realizar una segunda comprobación en el código de sincronización. Si la instancia está vacía, vuelva a crearla para que solo se cree un objeto.

sincronizado se puede agregar al método también se puede agregar al bloque de código

class Sync{
     public synchronized void test() {          
         System.out.println("test开始..");          
         
         try {              
             Thread.sleep(1000);          
         } catch (InterruptedException e) {             
             e.printStackTrace();          
         }          
             System.out.println("test结束..");      
      }  
}    

class MyThread extends Thread {        

     public void run() {          
        Sync sync = new Sync();          
        sync.test();      
     }  
}   
 
public class Main {        
    
      public static void main(String[] args) {          
          for (int i = 0; i < 3; i++) {              
             Thread thread = new MyThread();              
             thread.start();          
          }      
      }  
} 
} 复制代码

Resultado de la operación:

inicio de prueba ... inicio de prueba ... inicio de prueba ... final de prueba ... final de prueba ... final de prueba ...

No ha habido cambios, y no he visto que los sincronizados desempeñen un papel

Luego intentamos agregar sincronizado al bloque de código para reducir la granularidad del bloqueo

class Sync {        

      public void test() {          
         synchronized (Sync.class) {              
              System.out.println("test开始..");              
         
         try {                  
              Thread.sleep(1000);              
         } catch (InterruptedException e) {                 
              e.printStackTrace();              
         }              
         System.out.println("test结束..");          
      }      
}  
}    


class MyThread extends Thread {        
      public void run() {          
          Sync sync = new Sync();          
          sync.test();      
      }  
}   


public class Main {        
     
        public static void main(String[] args) {         
        
           for (int i = 0; i < 3; i++) {              
               Thread thread = new MyThread();              
               thread.start();          
           }      
        }  
}  复制代码

运行结果: 
test开始.. test结束.. test开始.. test结束.. test开始.. test结束..复制代码

Se puede ver que el bloqueo sincronizado no es esto, sino el objeto Clase Clase

Reentrada sincronizada

sincronizado es un mecanismo de bloqueo interno basado en atomicidad y es reentrante
Un hilo llama al método sincronizado mientras llama a otro método sincronizado del objeto dentro de su cuerpo de método
Cuando la subclase hereda la clase principal, la subclase también puede llamar al método de sincronización de la clase principal a través del bloqueo reentrante

Resumen

El bloqueo sincronizado es una instancia de la clase, o el objeto pasado, o esa oración, sincronizada para que solo un hilo a la vez pueda acceder a las variables o bloques de código.


Supongo que te gusta

Origin juejin.im/post/5e8ecce9f265da48027a2763
Recomendado
Clasificación