El artículo comparte 4 ejemplos de explicación detallada de sincronizado
1. Si agregar palabras clave sincronizadas
public class Threadtest {public static void main (string [] args) {ejemplo ejemplo = new Ejemplo (); Thread t1 = new Thread1 (ejemplo); Thread t2 = new Thread1 (ejemplo); t1.start (); t2.start (); }} Ejemplo de clase {Public sincronizado Void Expace () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute:" + i); }}} La clase Thread1 extiende el hilo {ejemplo privado de ejemplo; public Thread1 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.excute (); }}El resultado de salida de la palabra clave sincronizada es el siguiente
Primero se emitirá un conjunto de 0-4, y luego se emitirá el siguiente conjunto, y los dos subprocesos se ejecutarán en secuencia.
Excuto: 0
Excuto: 1
Excuto: 2
Excuto: 3
Excuto: 4
Excuto: 0
Excuto: 1
Excuto: 2
Excuto: 3
Excuto: 4
El resultado de salida de la palabra clave sincronizada es el siguiente
Dos hilos ejecutan el método de excute simultáneamente y simultáneamente
Excuto: 0
Excuto: 0
Excuto: 1
Excuto: 1
Excuto: 2
Excuto: 2
Excuto: 3
Excuto: 3
Excuto: 4
Excuto: 4
2. Situación múltiple de múltiples métodos
public class Threadtest {public static void main (string [] args) {ejemplo ejemplo = new Ejemplo (); Thread t1 = new Thread1 (ejemplo); Thread t2 = new Thread2 (ejemplo); t1.start (); t2.start (); }} Ejemplo de clase {Public sincronizado Void Expace () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute:" + i); }} public sincronizado sincronizado de escape1 () {for (int i = 0; i <5; ++ i) {try {hortes.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute1:" + i); }}} La clase Thread1 extiende el hilo {ejemplo privado de ejemplo; public Thread1 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.excute (); }} La clase Thread2 extiende el hilo {ejemplo privado de ejemplo; public thread2 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.exCute1 (); }}Los resultados de la ejecución son los siguientes
Lo mismo se ejecuta en secuencia, y se ejecuta un hilo antes de ejecutar otro hilo.
Excuto: 0
Excuto: 1
Excuto: 2
Excuto: 3
Excuto: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
Si se elimina la palabra clave sincronizada, los dos métodos se ejecutan simultáneamente y no tienen influencia mutua.
Pero como se escribe en la subrutina de ejemplo, incluso dos métodos:
El resultado de la ejecución siempre es la salida de un hilo y luego la ejecución de otro hilo.
ilustrar:
Si un objeto tiene múltiples métodos sincronizados, y un hilo ha entrado en un método sincronizado en un momento determinado, entonces otros subprocesos no pueden acceder a ningún método sincronizado del objeto antes de ejecutar el método.
en conclusión:
Cuando la palabra clave sincronizada modifica un método, el método se llama método de sincronización.
Cada objeto en Java tiene un bloqueo o un monitor. Cuando un hilo accede al método sincronizado de un objeto, el objeto está bloqueado y ningún otro hilo puede acceder al método sincronizado del objeto (aquí se refiere a todos los métodos de sincronización, no solo el mismo método). No es hasta que el hilo anterior completa el método de ejecución (o lanza una excepción), se libera el bloqueo del objeto, para que otros subprocesos puedan acceder al método sincronizado del objeto nuevamente.
Tenga en cuenta que el objeto está bloqueado en este momento. Si se trata de un objeto diferente, no hay una relación de restricción entre los objetos.
Al intentar construir un segundo objeto de hilo en el código, se pasa un nuevo objeto de ejemplo, entonces no hay restricción entre la ejecución de los dos hilos.
3. Método de sincronización estática
Cuando Static también modifica un método de palabra clave sincronizado, se ha dicho antes que un método de sincronización no estático bloqueará el objeto, pero el método estático no pertenece al objeto, sino a una clase, y bloqueará el objeto de clase de la clase donde se encuentra este método.
public class Threadtest {public static void main (string [] args) {ejemplo ejemplo = new Ejemplo (); Ejemplo Ejemplo2 = nuevo ejemplo (); Thread t1 = new Thread1 (ejemplo); Thread t2 = new Thread2 (Ejemplo2); t1.start (); t2.start (); }} Ejemplo de clase {Public Synchronized static void escape () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute:" + i); }} public sincronizado static void escape1 () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute1:" + i); }}} La clase Thread1 extiende el hilo {ejemplo privado de ejemplo; public Thread1 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.excute (); }} La clase Thread2 extiende el hilo {ejemplo privado de ejemplo; public Thread2 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.exCute1 (); }}Los resultados de la ejecución son los siguientes
Excuto: 0
Excuto: 1
Excuto: 2
Excuto: 3
Excuto: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
Si no hay un modificador estático y dos hilos pasan objetos diferentes, se ejecutarán simultáneamente al mismo tiempo.
Entonces, si se trata de un método estático (ejecutar () y ejecute2 (), ambas tienen palabras clave estáticas agregadas), incluso si se pasan objetos de ejemplo diferentes a dos subprocesos, los dos hilos todavía están restringidos entre sí. Uno debe ser ejecutado primero y luego el siguiente.
en conclusión:
Si un método sincronizado es estático, cuando un hilo accede al método, no bloquea el objeto donde se encuentra el método sincronizado, sino el objeto de clase correspondiente a la clase donde se encuentra el método sincronizado. En Java, no importa cuántos objetos tenga una clase, estos objetos corresponderán a un objeto de clase único. Por lo tanto, cuando un hilo accede a dos métodos estáticos y sincronizados de dos objetos de la misma clase, su orden de ejecución también es secuencial, es decir, un hilo ejecuta primero el método y el otro hilo comienza después de que se complete la ejecución.
4. Bloque sincronizado
sincronizado (objeto)
{
}
Significa que el hilo bloqueará el objeto objeto cuando se ejecute. (Tenga en cuenta que este objeto puede ser un objeto de cualquier clase, o puede usar esta palabra clave).
De esta manera, puede especificar el objeto bloqueado usted mismo.
public class Threadtest {public static void main (string [] args) {ejemplo ejemplo = new Ejemplo (); Thread t1 = new Thread1 (ejemplo); Thread t2 = new Thread2 (ejemplo); t1.start (); t2.start (); }} Ejemplo de clase {public void escape () {sincronizado (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute:" + i); }}} public void escape1 () {sincronizado (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); } System.out.println ("excute1:" + i); }}}}}}} La clase Thread1 extiende el hilo {ejemplo de ejemplo privado; public Thread1 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.excute (); }} La clase Thread2 extiende el hilo {ejemplo privado de ejemplo; public Thread2 (ejemplo de ejemplo) {this.example = ejemplo; } @Override public void run () {ejemplo.exCute1 (); }}Los resultados de la ejecución son los siguientes
Excuto: 0
Excuto: 1
Excuto: 2
Excuto: 3
Excuto: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
Exclusive1: 4
El efecto logrado por el programa de ejemplo 4 es el mismo que el del programa de ejemplo 2. Ambos hilos se ejecutan en secuencia, en lugar de simultáneamente. Cuando un hilo se ejecuta, el objeto se bloquea y el otro hilo no puede ejecutar el bloque correspondiente.
El método sincronizado es realmente equivalente a envolver todas las declaraciones en el método con un bloque sincronizado, y luego pasar esta palabra clave en los soportes del bloque sincronizado. Por supuesto, si se trata de un método estático, el objeto de clase debe bloquearse.
Quizás solo unas pocas líneas de código en un método implicarán problemas de sincronización de subprocesos, por lo que el bloque sincronizado controla el acceso de múltiples hilos de manera más granular que el método sincronizado. Solo no se puede acceder al contenido en el bloque sincronizado mediante múltiples hilos al mismo tiempo, y aún se puede acceder a otras declaraciones en el método mediante múltiples hilos al mismo tiempo (incluso antes y después del bloque sincronizado).
en conclusión:
El método sincronizado es un control concurrente de grano grueso. En un momento determinado, solo un hilo puede ejecutar el método sincronizado;
El bloque sincronizado es un control de concurrencia de grano fino, que solo sincroniza el código en el bloque. Se puede acceder a otros códigos ubicados en el método y que no sean bloques sincronizados mediante múltiples hilos al mismo tiempo.
Lo anterior se trata del método de sincronización de bloque sincronizado de la programación multiproceso Java. Espero que sea útil para el aprendizaje de todos.