"Hallo, Amigo! Gisteren hebben we de voordelen en gemakken van multithreading besproken. Nu is het tijd om naar de nadelen te kijken. En die zijn helaas niet klein."

Eerder keken we naar een programma als een verzameling objecten die elkaars methoden aanroepen. Nu wordt alles een beetje ingewikkelder. Een programma lijkt meer op een set objecten waar verschillende "kleine robots" (threads) doorheen kruipen en de opdrachten uitvoeren die in de methoden zijn opgenomen.

Deze nieuwe interpretatie heft de eerste niet op. Het zijn nog steeds objecten en ze noemen elkaars methoden nog steeds. Maar we moeten niet vergeten dat er verschillende threads zijn en dat elke thread zijn eigen taak of taak heeft.

Een programma wordt steeds ingewikkelder. Verschillende threads veranderen de status van verschillende objecten op basis van de taken die ze uitvoeren. En ze kunnen op elkaars tenen trappen.

Maar de ergste dingen gebeuren diep in de Java-machine. Zoals ik al zei, wordt de schijnbare gelijktijdigheid van threads bereikt door het feit dat de processor constant van de ene thread naar de andere overschakelt. Het schakelt over naar een thread, werkt 10 milliseconden, schakelt over naar de volgende thread, werkt 10 milliseconden, enzovoort. En hierin schuilt het probleem: deze schakelaars kunnen op de meest ongelegen momenten plaatsvinden. Overweeg dit voorbeeld:

Code van de eerste thread Code van de tweede 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 ();
Wat we verwachtten te laten zien
Nick is 15 jaar
Lena is 21 jaar oud
Daadwerkelijke uitvoering van de code Code van de eerste thread Code van de tweede 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 ();
Wat er daadwerkelijk wordt weergegeven
Nick is  Lena is   15  21  jaar oud
jaar oud

En hier is nog een voorbeeld:

Code Beschrijving
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
De swap-methode swapde waarden van de name1en name2variabelen.

Wat kan er gebeuren als het vanuit twee threads tegelijk wordt aangeroepen?

Daadwerkelijke uitvoering van de code Code van de eerste thread Code van de tweede 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;
het komt neer op
Beide variabelen hebben de waarde «Lena».
Het «Ally»-object heeft het niet gehaald. Het is verloren.

"Wie had gedacht dat dit soort fouten mogelijk zijn met zo'n eenvoudige toewijzing?!"

"Ja, dit probleem heeft een oplossing. Maar we praten er later over - mijn keel is droog."