"Hei, Amigo! I går diskuterte vi fordelene og bekvemmelighetene ved multithreading. Nå er det på tide å se på ulempene. Og de er dessverre ikke små."

Tidligere så vi på et program som et sett med objekter som kaller hverandres metoder. Nå blir alt litt mer komplisert. Et program er mer som et sett med objekter som har flere "små roboter" (tråder) som kryper gjennom seg og utfører kommandoene i metodene.

Denne nye tolkningen kansellerer ikke den første. De er fortsatt objekter, og de kaller fortsatt hverandres metoder. Men vi må huske at det er flere tråder, og hver tråd gjør sin egen jobb eller oppgave.

Et program blir mer komplisert. Ulike tråder endrer tilstanden til forskjellige objekter basert på oppgavene de utfører. Og de kan tråkke hverandre på tærne.

Men de verste tingene skjer dypt inne i Java-maskinen. Som jeg allerede har sagt, oppnås den tilsynelatende samtidigheten av tråder ved at prosessoren hele tiden bytter fra en tråd til en annen. Den bytter til en tråd, fungerer i 10 millisekunder, bytter til neste tråd, fungerer i 10 millisekunder, og så videre. Og her ligger problemet: disse bryterne kan oppstå på de mest uhensiktsmessige øyeblikkene. Tenk på dette eksemplet:

Koden til den første tråden Koden til den andre tråden
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 ();
Hva vi forventet å bli vist
Nick er 15 år
Lena er 21 år
Faktisk kodeutførelse Koden til den første tråden Koden til den andre tråden
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 ();
Hva som faktisk vises
Nick er  Lena er   15  21  år
gammel

Og her er et annet eksempel:

Kode Beskrivelse
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Byttemetoden swapverdiene til variablene name1og name2.

Hva kan skje hvis det kalles opp fra to tråder samtidig?

Faktisk kodeutførelse Koden til den første tråden Koden til den andre tråden
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;
Bunnlinjen
Begge variablene har verdien «Lena».
«Ally»-objektet klarte det ikke. Det er tapt.

"Hvem ville ha gjettet at feil som dette er mulig med en så enkel oppdragsoperasjon?!"

"Ja, dette problemet har en løsning. Men vi snakker om dette litt senere - halsen min er tørr."