Sorunun Tarihçesi:
Java’nın çıkışından itibaren geliştiriciler, ortak kaynaklara eşzamanlı erişim problemiyle karşılaştılar. Bu sorunları çözmek için, en önemli yüksek seviyeli senkronizasyon primitiflerinden biri olan synchronized anahtar modifikatörü tanıtıldı.
Problem:
Senkronizasyon olmadan çok iş parçacıklı uygulamalarda paylaşılan kaynaklar bozulabilir: veri yarışı (data race) oluşur, nesnenin durumu öngörülemez hale gelir.
Çözüm:
synchronized, bir metodun veya kod bloğunun monitörünü düzenleyerek, kritik bölgeye aynı anda yalnızca bir iş parçacığının erişimini sağlar. İş parçacığı senkronizasyonu metodun veya bloğun düzeyinde gerçekleştirilebilir.
Örnek bir nesnenin kilitlenmesi:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Ayrıca blokları da senkronize edebilirsiniz:
public void safeIncrement() { synchronized(this) { count++; } }
Temel özellikler:
synchronized metod ile synchronized blok arasında ne fark vardır?
synchronized metodu, mevcut nesne (this) veya sınıf için (eğer metod statik ise) tüm metodu kilitler. Blok ise yalnızca gerekli kod parçasını senkronize etmeye ve herhangi bir nesneyi kilitlemeye olanak tanır.
İki farklı iş parçacığı, aynı nesnenin iki farklı synchronized metoduna aynı anda girebilir mi?
Hayır, eğer metodlar aynı monitör üzerinde senkronizeyse (this). Eğer farklı monitörler kullanılıyorsa, evet.
synchronized modifikatörü, iş parçacıkları arasındaki değişkenlerin görünürlüğünü etkiler mi?
Evet, synchronized bloğuna girmek iş parçacıklarının önbelleklerini sıfırlar ve değişkenlerin değerlerini günceller (happens-before ilişkisi).
Geliştirici, sınıfın statik metodlarını örnek nesnesi üzerinde senkronize eder, bu da farklı örnekler aracılığıyla kullanıldığında doğruluğu garanti etmez.
Artılar:
Eksiler:
Ortak kaynağı kullanan tüm metodlar, aynı nesne-monitör üzerinde senkronize edilir, kritik bölgenin alanı minimumdur.
Artılar:
Eksiler: