"Szervusz, Amigo! Tegnap megbeszéltük a többszálú használat előnyeit és kényelmét. Most itt az ideje, hogy megvizsgáljuk a hátrányokat. És sajnos nem kicsik."

Korábban úgy tekintettünk a programokra, mint egymás metódusait meghívó objektumok halmazára. Most minden kicsit bonyolultabbá válik. A program inkább olyan objektumok halmaza, amelyekben több "kis robot" (szál) mászik át, és végrehajtja a metódusokban foglalt parancsokat.

Ez az új értelmezés nem törli az elsőt. Még mindig tárgyak, és továbbra is egymás módszereit hívják. De emlékeznünk kell arra, hogy több szál is létezik, és mindegyik szál elvégzi a saját feladatát vagy feladatát.

Egy program egyre bonyolultabb. A különböző szálak az általuk elvégzett feladatok alapján változtatják meg a különböző objektumok állapotát. És ráléphetnek egymás lábujjára.

De a legrosszabb dolgok a Java gép mélyén történnek. Ahogy már mondtam, a szálak látszólagos egyidejűsége azáltal érhető el, hogy a processzor folyamatosan vált egyik szálról a másikra. Vált egy szálra, 10 ezredmásodpercig működik, átvált a következő szálra, működik 10 ezredmásodpercig, és így tovább. És itt van a probléma: ezek a váltások a leginkább alkalmatlan pillanatokban fordulhatnak elő. Tekintsük ezt a példát:

Az első szál kódja A második szál kódja
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 ();
Amit vártunk, hogy megjelenjenek
Nick 15 éves
Lena 21 éves
Tényleges kódvégrehajtás Az első szál kódja A második szál kódja
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 ();
Ami valójában megjelenik
Nick  Lena   15  21  éves
_

És itt van egy másik példa:

Kód Leírás
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
A swap módszer a és a változók swapértékeit .name1name2

Mi történhet, ha egyszerre két szálból hívják?

Tényleges kódvégrehajtás Az első szál kódja A második szál kódja
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;
Alsó vonal
Mindkét változó "Lena" értékű.
A „Szövetséges” objektum nem jutott be. Elveszett.

"Ki gondolta volna, hogy egy ilyen egyszerű hozzárendelési művelettel ilyen hibák előfordulhatnak?!"

"Igen, ennek a problémának van megoldása. De erről egy kicsit később beszélünk – kiszáradt a torkom."