"Hej, Amigo! Igår diskuterade vi fördelarna och bekvämligheterna med multithreading. Nu är det dags att titta på nackdelarna. Och tyvärr är de inte små."

Tidigare såg vi på ett program som en uppsättning objekt som anropar varandras metoder. Nu blir allt lite mer komplicerat. Ett program är mer som en uppsättning objekt som har flera "små robotar" (trådar) som kryper igenom och utför kommandona i metoderna.

Denna nya tolkning avbryter inte den första. De är fortfarande föremål, och de kallar fortfarande varandras metoder. Men vi måste komma ihåg att det finns flera trådar, och varje tråd gör sitt eget jobb eller uppgift.

Ett program blir mer komplicerat. Olika trådar ändrar tillståndet för olika objekt baserat på de uppgifter de utför. Och de kan trampa varandra på tårna.

Men det värsta händer djupt inne i Java-maskinen. Som jag redan har sagt uppnås den skenbara samtidigheten av trådar genom att processorn ständigt växlar från en tråd till en annan. Den växlar till en tråd, fungerar i 10 millisekunder, växlar till nästa tråd, fungerar i 10 millisekunder, och så vidare. Och här ligger problemet: dessa växlar kan inträffa vid de mest olämpliga ögonblicken. Tänk på det här exemplet:

Koden för den första tråden Koden för den andra 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 ();
Vad vi förväntade oss att visas
Nick är 15 år
Lena är 21 år
Faktisk kodexekvering Koden för den första tråden Koden för den andra 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 ();
Vad som faktiskt visas
Nick är  Lena är   15  21  år
gammal

Och här är ett annat exempel:

Koda Beskrivning
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Swapmetoden swapvärdena för variablerna name1och .name2

Vad kan hända om det anropas från två trådar samtidigt?

Faktisk kodexekvering Koden för den första tråden Koden för den andra 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;
Poängen
Båda variablerna har värdet «Lena».
Objektet «Ally» klarade sig inte. Det är förlorat.

"Vem skulle ha anat att sådana här fel är möjliga med en så enkel tilldelningsoperation?!"

"Ja, det här problemet har en lösning. Men vi ska prata om det här lite senare - min hals är torr."