"Merhaba Amigo! Dün çoklu okumanın faydalarını ve kolaylıklarını tartıştık. Şimdi dezavantajlarına bakma zamanı. Ve ne yazık ki bunlar küçük değiller."

Önceden, bir programa birbirinin metotlarını çağıran bir dizi nesne olarak bakmıştık. Şimdi her şey biraz daha karmaşık hale geliyor. Bir program daha çok, içinde gezinen ve yöntemlerde yer alan komutları yürüten birkaç "küçük robot" (thread) içeren bir nesneler kümesi gibidir.

Bu yeni yorum ilkini iptal etmez. Hâlâ nesnedirler ve hâlâ birbirlerinin yöntemlerini çağırırlar. Ancak birkaç iş parçacığı olduğunu ve her iş parçacığının kendi işini veya görevini yaptığını unutmamalıyız.

Bir program daha karmaşık hale geliyor. Farklı iş parçacıkları, gerçekleştirdikleri görevlere göre farklı nesnelerin durumunu değiştirir. Ve birbirlerinin ayak parmaklarına basabilirler.

Ancak en kötü şeyler Java makinesinin derinliklerinde olur. Daha önce de söylediğim gibi, iş parçacıklarının görünürdeki eşzamanlılığı, işlemcinin sürekli olarak bir iş parçacığından diğerine geçmesi gerçeğiyle elde edilir. Bir iş parçacığına geçer, 10 milisaniye çalışır, bir sonraki iş parçacığına geçer, 10 milisaniye çalışır, vb. Ve sorun burada yatıyor: Bu geçişler en uygunsuz anlarda gerçekleşebilir. Bu örneği göz önünde bulundurun:

İlk iş parçacığının kodu İkinci iş parçacığının kodu
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 ();
Görüntülenmesini beklediğimiz şey
Nick 15 yaşında
Lena 21 yaşında
Gerçek kod yürütme İlk iş parçacığının kodu İkinci iş parçacığının kodu
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 ();
Gerçekte ne gösteriliyor
Nick  Lena   15  21  yaşında
_

Ve işte başka bir örnek:

kod Tanım
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
Swap yöntemi, ve swapdeğişkenlerinin değerlerini değiştirir .name1name2

Aynı anda iki iş parçacığından çağrılırsa ne olabilir?

Gerçek kod yürütme İlk iş parçacığının kodu İkinci iş parçacığının kodu
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;
Alt çizgi
Her iki değişken de «Lena» değerine sahiptir.
«Ally» nesnesi bunu başaramadı. Kayıp.

"Bu kadar basit bir atama işleminde bunun gibi hataların mümkün olduğunu kim tahmin edebilirdi ki?!"

"Evet, bu sorunun bir çözümü var. Ama bunu biraz sonra konuşacağız - boğazım kurudu."