sintaxis significado reservadas que programar programacion palabras libro lenguaje cómo codigos java synchronized

significado - Aprendizaje de Java, uso de palabras clave sincronizadas.



que es java (2)

así que estaba probando con synchronized palabra clave synchronized . Aquí hay un ejemplo que probé:

public class MyTest { static int i = 0; public static void main(String[] args) { new Thread(t1).start(); new Thread(t2).start(); } private static void countMe(String name){ i++; System.out.println("Current Counter is: " + i + ", updated by: " + name); } private static Runnable t1 = new Runnable() { public void run() { try{ for(int i=0; i<5; i++){ countMe("t1"); } } catch (Exception e){} } }; private static Runnable t2 = new Runnable() { public void run() { try{ for(int i=0; i<5; i++){ countMe("t2"); } } catch (Exception e){} } }; }

Cuando lo ejecuto, la salida de llamar countMe() método countMe() desde dos subprocesos genera esta salida:

Current Counter is: 1 Current Counter is: 2 Current Counter is: 4 Current Counter is: 5 Current Counter is: 6 Current Counter is: 7 Current Counter is: 3 Current Counter is: 8 Current Counter is: 9 Current Counter is: 10

Y cuando cambio el método countMe() a:

private synchronized static void countMe(){ i++; System.out.println("Current Counter is: " + i); }

Obtengo esta salida:

Current Counter is: 1 Current Counter is: 2 Current Counter is: 3 Current Counter is: 4 Current Counter is: 5 Current Counter is: 6 Current Counter is: 7 Current Counter is: 8 Current Counter is: 9 Current Counter is: 10

Aunque esto me permite comprender claramente el propósito de la synchronized , quiero saber si hay alguna otra razón también, que podamos usar synchronized . O lo que he hecho aquí, ¿es la única razón por la que necesitamos el uso de esta palabra clave synchronized ?

Gracias.

EDITAR: Otra cosa con la que estoy confundido es que, en la primera salida, ¿por qué el contador se fue a 3 después de 7. Me parece un poco imposible, pero los resultados similares ocurren cada vez que lo intento, es normal?


Dos cosas:

En primer lugar, no es posible intercalar dos invocaciones de métodos sincronizados en el mismo objeto. Cuando un subproceso está ejecutando un método sincronizado para un objeto, todos los demás subprocesos que invocan métodos sincronizados para el mismo bloque de objeto (suspensión de ejecución) hasta que el primer subproceso se realiza con el objeto.

Segundo, cuando un método sincronizado sale, automáticamente establece una relación de suceso antes de cualquier invocación posterior de un método sincronizado para el mismo objeto. Esto garantiza que los cambios en el estado del objeto sean visibles para todos los subprocesos.

Los métodos sincronizados permiten una estrategia simple para prevenir la interferencia de subprocesos y los errores de consistencia de la memoria: si un objeto es visible a más de un subproceso, todas las lecturas o escrituras en las variables de ese objeto se realizan mediante métodos sincronizados. (Una excepción importante: los campos finales, que no se pueden modificar después de que se construye el objeto, se pueden leer de manera segura a través de métodos no sincronizados, una vez que se construye el objeto).

fuente: http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html


Vulkanino dio una buena respuesta a su pregunta principal, así que solo abordaré su pregunta sobre la impresión 3 después de la 7.

El 3 puede imprimir después del 7 porque en realidad hay mucho más código de bytes en sus declaraciones que el código de Java.

Voy a ampliar en eso.

Llama

System.out.println("Current Counter is: " + i);

y ocurre en una línea de código Java, pero en realidad lo que sucede es que se crea una cadena y luego esa cadena se pasa a println. El método println en sí tiene que hacer un poco de procesamiento antes de que realmente escriba la línea en la consola.

Conceptualmente, algo como lo siguiente está sucediendo.

String printlnString = "Current Counter is: 3" --> maybe the other thread executes here System.out.println(printlnString); --> or maybe the other thread executes here i is now equal to 7 and the console has "Current Counter is: 7" println writes "Current Counter is: 3" to console