"Hej, Amigo! I går diskuterede vi fordelene og bekvemmelighederne ved multithreading. Nu er det tid til at se på ulemperne. Og desværre er de ikke små."

Tidligere så vi på et program som et sæt objekter, der kalder hinandens metoder. Nu bliver alt lidt mere kompliceret. Et program er mere som et sæt objekter, der har flere "små robotter" (tråde), der kravler igennem sig og udfører kommandoerne i metoderne.

Denne nye fortolkning annullerer ikke den første. De er stadig objekter, og de kalder stadig hinandens metoder. Men vi skal huske, at der er flere tråde, og hver tråd udfører sit eget job eller sin opgave.

Et program bliver mere kompliceret. Forskellige tråde ændrer tilstanden af ​​forskellige objekter baseret på de opgaver, de udfører. Og de kan træde hinanden over tæerne.

Men de værste ting sker dybt inde i Java-maskinen. Som jeg allerede har sagt, opnås den tilsyneladende samtidighed af tråde ved, at processoren konstant skifter fra en tråd til en anden. Den skifter til en tråd, arbejder i 10 millisekunder, skifter til den næste tråd, arbejder i 10 millisekunder og så videre. Og heri ligger problemet: disse skift kan forekomme på de mest uhensigtsmæssige tidspunkter. Overvej dette eksempel:

Koden for den første tråd Kode for den anden tråd
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 ();
Hvad vi forventede at blive vist
Nick er 15 år
Lena er 21 år
Faktisk kodeudførelse Koden for den første tråd Kode for den anden tråd
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 ();
Hvad der faktisk vises
Nick er  Lena er   15  21  år
gammel

Og her er endnu et eksempel:

Kode Beskrivelse
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Swap-metoden swapværdierne af variablerne name1og name2.

Hvad kan der ske, hvis det kaldes fra to tråde på samme tid?

Faktisk kodeudførelse Koden for den første tråd Kode for den anden tråd
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;
Bundlinjen
Begge variabler har værdien «Lena».
«Ally»-objektet nåede det ikke. Det er tabt.

"Hvem ville have gættet, at fejl som denne er mulige med sådan en simpel opgavehandling?!"

"Ja, dette problem har en løsning. Men vi taler om det lidt senere - min hals er tør."