"¡Hola, amigo! Ayer discutimos los beneficios y las ventajas de los subprocesos múltiples. Ahora es el momento de ver las desventajas. Y, desafortunadamente, no son pequeñas".

Anteriormente, vimos un programa como un conjunto de objetos que llaman a los métodos de los demás. Ahora todo se vuelve un poco más complicado. Un programa es más como un conjunto de objetos que tiene varios "pequeños robots" (hilos) que se arrastran a través de él y ejecutan los comandos contenidos en los métodos.

Esta nueva interpretación no cancela la primera. Todavía son objetos, y todavía llaman a los métodos de los demás. Pero tenemos que recordar que hay varios hilos, y cada hilo hace su propio trabajo o tarea.

Un programa es cada vez más complicado. Diferentes subprocesos cambian el estado de diferentes objetos en función de las tareas que realizan. Y pueden pisar los dedos de los pies unos a otros.

Pero lo peor sucede en el interior de la máquina Java. Como ya he dicho, la aparente simultaneidad de hilos se logra por el hecho de que el procesador cambia constantemente de un hilo a otro. Cambia a un subproceso, funciona durante 10 milisegundos, cambia al siguiente subproceso, funciona durante 10 milisegundos, y así sucesivamente. Y aquí radica el problema: estos cambios pueden ocurrir en los momentos más inoportunos. Considere este ejemplo:

Código del primer hilo Código del segundo hilo
System.out.print ("Nick is");
System.out.print ("");
System.out.print ("15");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
System.out.print ("Lena is");
System.out.print ("");
System.out.print ("21");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
Lo que esperábamos que se mostrara
Nick tiene 15 años
Lena tiene 21 años
Ejecución de código real Código del primer hilo Código del segundo hilo
System.out.print ("Nick is");
System.out.print ("Lena is");
System.out.print (" ");
System.out.print (" ");
System.out.print ("15");
System.out.print ("21");
System.out.print (" ");
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
System.out.print ("years old");
System.out.println ();
System.out.print ("Nick is");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("15");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
//other thread is running
//other thread is running
//other thread is running
System.out.print ("Lena is");
System.out.print (" ");
//other thread is running
//other thread is running
System.out.print ("21");
System.out.print (" ");
//other thread is running
//other thread is running
//other thread is running
System.out.print ("years old");
System.out.println ();
Lo que realmente se muestra
Nick es  Lena tiene   15  21  años
años

Y aquí hay otro ejemplo:

Código Descripción
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
El método de intercambio swapde los valores de las variables name1y name2.

¿Qué podría pasar si se llama desde dos subprocesos al mismo tiempo?

Ejecución de código real Código del primer hilo Código del segundo hilo
String s1 = name1; //Ally
name1 = name2; //Lena
String s2 = name1; //Lena(!)
name1 = name2; //Lena
name2 = s1; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s1;
//other thread is running
//other thread is running
//other thread is running
String s2 = name1;
name1 = name2;
//other thread is running
name2 = s2;
La línea de fondo
Ambas variables tienen el valor «Lena».
El objeto «Ally» no lo logró. Esta perdido.

"¡¿Quién habría adivinado que errores como este son posibles con una operación de asignación tan simple?!"

"Sí, este problema tiene solución. Pero hablaremos de esto un poco más tarde, tengo la garganta seca".