¿Qué significa sincronización en Java?
Suponiendo que P1 y P2 son objetos diferentes en la misma clase, y la clase define un bloque de sincronización o un método de sincronización para las siguientes situaciones, entonces tanto P1 como P2 puede llamarlos.
1. Cuando se utiliza sincronizado como modificador de función, el código de muestra es el siguiente:
Método vacío sincronizado públicoAAA()
{
//....
}
Este también es un método sincronizado, entonces, ¿qué objeto está sincronizado bloqueado esta vez? Bloquea el objeto en el que se llama a este método sincronizado. En otras palabras, cuando un objeto P1 ejecuta este método de sincronización en diferentes subprocesos, se excluirán entre sí y lograrán la sincronización. Sin embargo, otro objeto P2 generado por la clase a la que pertenece este objeto puede llamar libremente a métodos con la palabra clave sincronizada.
El código de ejemplo anterior es equivalente al siguiente código:
método public voidAAA()
{
sincronizado (esto) / / (1 )
{
//.....
}
}
( 1) ¿Qué significa? Se refiere al objeto en el que se llama al método, como P1, que es un método sincronizado que esencialmente aplica la sincronización a la referencia del objeto: un subproceso que posee el bloqueo del objeto P1 puede llamar al método sincronizado en P1, y para P2, el método sincronizado en P1 El bloqueo no importa. Cuando es irrelevante, el programa también puede escapar del control del mecanismo de sincronización en este caso, causando confusión de datos: (
2. Bloque sincronizado, el código de muestra es el siguiente:
público método vacío3( SomeObject so)
{
sincronizado(so)
{
//.....
}
}
En este punto, el candado es el objeto, y quien obtenga el candado puede ejecutar el código que controla cuando tiene un objeto explícito como. el bloqueo, puedes escribir tu programa de esta manera, pero cuando no tienes un objeto explícito como bloqueo y solo quieres sincronizar un fragmento de código, puedes crear una variable de instancia especial (debe ser un objeto) como; un bloqueo:
clase Foo implementa Runnable
{
byte privado[] lock = nuevo byte[0] // variable de instancia especial
;Método de anulación pública A()
{
sincronizado(bloqueo) { //...}
}
/ /.....
}
Nota: Crear un objeto de matriz de bytes de longitud cero es más económico que crear cualquier objeto; mire el código de bytes compilado: generar un objeto de longitud cero El objeto byte[] requiere solo 3 líneas de código de operación, y Object lock = new Object() requiere 7 líneas de código de operación.
3. Aplicar sincronización a funciones estáticas. El código de muestra es el siguiente:
Class Foo
{
vacío estático sincronizado público. métodoAAA( ) // función estática sincronizada
{
//....
}
método public voidBBB()
{
sincronizado(Foo.class) // Constante literal de clase (constante literal de nombre de clase)
}
}
El código del método método BBB() es un ejemplo del uso de un literal de clase como bloqueo. El efecto es el mismo que el de una función estática sincronizada. El bloqueo especial obtenido es la clase (Clase) a la que está actualmente el objeto. llamar a este método pertenece a un objeto específico generado por esta clase).
Recuerde que en el libro "Java efectivo", verá que Foo.class y P1.getClass() tienen diferentes efectos en los bloqueos de sincronización. No puede usar P1.getClass() para bloquear la clase. . P1 se refiere al objeto generado por la clase Foo.
Se puede inferir de esto: si una clase define una función estática síncrona A y una función de instancia síncrona B, entonces el mismo objeto Obj en esta clase accede a estos dos objetos respectivamente en acceso multiproceso. Al utilizar los métodos A y B, la sincronización no se producirá porque sus bloqueos no son los mismos. El bloqueo del método A es el objeto Obj, mientras que el bloqueo del método B es la clase a la que pertenece Obj.