« Bonjour, Amigo ! Hier, nous avons discuté des avantages et des commodités du multithreading. Maintenant, penchons-nous sur ses inconvénients. Et, malheureusement, ils ne sont pas négligeables. »

Précédemment, nous avons envisagé un programme comme un ensemble d'objets qui appellent les méthodes des uns et des autres. Maintenant, tout cela se complique un peu. Un programme ressemble plus à un ensemble d'objets avec plusieurs « petits robots » (threads) qui rampent un peu partout et exécutent les commandes contenues dans les méthodes.

Cette nouvelle interprétation n'annule pas la première. Ce sont toujours des objets, et ils appellent toujours les méthodes des uns et des autres. Mais nous devons nous rappeler qu'il y a plusieurs threads, et que chaque thread fait son propre travail ou sa propre tâche.

Un programme est de plus en plus compliqué. Différents threads changent l'état de différents objets en fonction des tâches qu'ils exécutent. Et bien sûr, ils peuvent parfois se marcher sur les pieds.

Mais le pire se passe au plus profond de la machine Java. Comme je l'ai déjà dit, la simultanéité apparente des threads est obtenue en faisant constamment passer le processeur d'un thread à l'autre. Il passe à un thread, l'exécute pendant 10 millisecondes, passe à un autre thread, l'exécute pendant 10 millisecondes, et ainsi de suite. Et c'est là que le problème se pose : ces basculements peuvent se produire aux moments les plus inopportuns. Prenons l'exemple suivant :

Code du premier thread Code du second thread
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 ();
Ce que nous nous attendions à voir s'afficher
Nick a 15 ans
Lena a 21 ans
Exécution réelle du code Code du premier thread Code du second thread
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 ();
Ce qui est réellement affiché
Nick a Lena a  15 21 ans
ans

Et voici un autre exemple :

Code Description
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
La méthode swap échange les valeurs des variables name1 et name2.

Qu'est-ce qui pourrait arriver si elle était appelée à partir de deux threads en même temps ?

Exécution réelle du code Code du premier thread Code du second thread
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;
Conclusion
Les deux variables ont la valeur 'Lena'.
L'objet 'Ally' n'est pas arrivé à temps. Il a été perdu.

« Qui aurait pensé que des erreurs de ce genre étaient possibles avec une opération d'affectation aussi simple !? »

« Ce problème a une solution. Mais nous en reparlerons un peu plus tard ; je commence à avoir la gorge un peu sèche. »