"Merhaba Amigo! Her derde deva bir ilacımız var - tüm hastalıkların tedavisi. Daha önce gördüğümüz gibi, kontrolsüz iplik değiştirme bir sorun."

"Neden ileti dizileri bir sonraki ileti dizisine ne zaman geçeceklerine kendileri karar veremiyor? Yapmaları gereken her şeyi yapıp ardından, «Bitirdim!» sinyali veriyorlar mı?"

"İş parçacıklarının geçişleri kontrol etmesine izin vermek daha da büyük bir sorun olur. Kötü yazılmış bir kodunuz olduğunu ve iş parçacığının CPU'yu asla teslim etmediğini varsayalım. Eskiden bu böyle çalışıyordu. Ve tam bir kabustu."

"Tamam. Peki çözüm nedir?"

" Diğer ileti dizilerini engelleme.  Bu şekilde çalışır."

Paylaşımlı nesneleri ve/veya kaynakları kullanmaya çalıştıklarında iş parçacıklarının birbirleriyle etkileşime girdiği açık hale geldi . Konsol çıktılı örnekte gördüğümüz gibi: bir konsol var ve tüm iş parçacıkları ona çıkıyor. Dağınık.

Böylece özel bir nesne icat edildi: muteks . Banyo kapısının üzerinde "müsait / meşgul" yazan bir işaret gibi . İki durumu vardır: nesne kullanılabilir veya meşgul . Bu durumlar ayrıca "kilitli" ve "kilitsiz" olarak da adlandırılır.

Bir iş parçacığı, diğer iş parçacıklarıyla paylaşılan bir nesneye ihtiyaç duyduğunda, nesneyle ilişkili muteksi kontrol eder. Muteksin kilidi açılırsa, iş parçacığı onu kilitler ("dolu" olarak işaretler) ve paylaşılan kaynağı kullanmaya başlar. İş parçacığı işini yaptıktan sonra, muteksin kilidi açılır ("mevcut" olarak işaretlenir).

Eğer iş parçacığı nesneyi kullanmak isterse ve muteks kilitliyse iş parçacığı beklerken uyku moduna geçer. Muteksin kilidi işgal edilen iş parçacığı tarafından nihayet açıldığında, iş parçacığımız onu hemen kilitler ve çalışmaya başlar. Banyo kapısı işaretiyle yapılan benzetme mükemmeldir.

"Peki bir muteksle nasıl çalışırım? Özel nesneler yaratmam gerekiyor mu?"

"Bundan çok daha basit. Java'nın yaratıcıları bu muteksi Object sınıfının içine yerleştirdi. Yani onu yaratmanıza bile gerek yok. Bu, her nesnenin bir parçasıdır. Her şey şu şekilde çalışır:"

kod Tanım
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Takas yöntemi, isim1 ve isim2 değişkenlerinin değerlerini değiştirir.

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
name2 = s1; //Ally

String s2 = name1; //Lena
name1 = name2; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
name2 = s1;
//the thread waits until the mutex is unlocked

String s2 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s2;
Alt çizgi
Değişkenlerin değerleri, orijinal yerlerine geri dönerek iki kez değiştirildi.

synchronized anahtar sözcüğüne dikkat edin  .

"Evet, bu ne anlama geliyor?"

"Bir iş parçacığı senkronize olarak işaretlenmiş bir kod bloğuna girdiğinde, Java makinesi senkronize kelimesinden sonra parantez içinde belirtilen nesnenin muteksini hemen kilitler. Bizim iş parçacığımız onu terk edene kadar başka hiçbir iş parçacığı bu bloğa giremez. İş parçacığımız ayrılır ayrılmaz senkronize olarak işaretlenen blok, muteksin kilidi anında ve otomatik olarak açılır ve başka bir iş parçacığı tarafından alınabilecektir."

Mutex doluysa, iş parçacığımız hareketsiz duracak ve serbest kalmasını bekleyecektir.

"Çok basit ve çok zarif. Bu çok güzel bir çözüm."

"Evet. Ama bu durumda ne olacağını düşünüyorsun?"

kod Tanım
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public void swap2()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Swap ve swap2 yöntemleri aynı muteksi ( bu nesne) paylaşır.

Bir iş parçacığı takas yöntemini ve başka bir iş parçacığı takas2 yöntemini çağırırsa ne olur?

"Muteks aynı olduğu için, ikinci iş parçacığı, ilk iş parçacığı senkronize bloktan çıkana kadar beklemek zorunda kalacak. Bu nedenle, eşzamanlı erişimde herhangi bir sorun olmayacak."

"Aferin Amigo! Doğru cevap bu!"

Şimdi, Sync'in sadece kod bloklarını değil, metotları da işaretlemek için kullanılabileceğini belirtmek isterim . İşte bunun anlamı:

kod gerçekten ne oluyor
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public synchronized void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}

public static synchronized void swap2()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public static void swap2()
{
synchronized (MyClass.class)
{
String s = name1;
name1 = name2;
name2 = s;
}
}