"Здравей, Амиго! Вчера обсъждахме предимствата и удобствата на многопоточността. Сега е време да разгледаме недостатъците. А те, за съжаление, не са малко."

Преди това разглеждахме програмата като набор от обекти, които извикват взаимно методи. Сега всичко става малко по-сложно. Програмата е по-скоро набор от обекти, който има няколко "малки робота" (нишки), които пълзят през него и изпълняват командите, съдържащи се в методите.

Това ново тълкуване не отменя първото. Те все още са обекти и все още си извикват методи. Но трябва да помним, че има няколко нишки и всяка нишка върши своя собствена работа or задача.

Програмата става все по-сложна. Различните нишки променят състоянието на различни обекти въз основа на задачите, които изпълняват. И могат да си стъпват на пръстите.

Но най-лошите неща се случват дълбоко в Java машината. Както вече казах, привидната едновременност на нишките се постига от факта, че процесорът постоянно превключва от една нишка към друга. Превключва към нишка, работи 10 мorсекунди, превключва към следващата нишка, работи 10 мorсекунди и т.н. И тук е проблемът: тези превключвания могат да се появят в най-неподходящите моменти. Помислете за този пример:

Код на първата нишка Код на втората нишка
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 ();
Това, което очаквахме да бъде показано
Ник е на 15 години,
Лена е на 21 години
Действително изпълнение на codeа Код на първата нишка Код на втората нишка
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 ();
Какво всъщност се показва
Ник е  Лена е   на 15  21  години

И ето още един пример:

Код Описание
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Методът за размяна swapна стойностите на променливите name1и name2.

Какво може да се случи, ако бъде извикан от две нишки едновременно?

Действително изпълнение на codeа Код на първата нишка Код на втората нишка
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;
Долния ред
И двете променливи имат стойността «Лена».
Обектът «Съюзник» не успя. Загубено е.

"Кой би предположил, че грешки като тази са възможни с такава проста операция за присвояване?!"

"Да, този проблем има решение. Но ще поговорим за това малко по-късно - гърлото ми е пресъхнало."