ProgramlamaBackend Geliştirici

Java'daki synchronized mekanizması nasıl çalışır? Ne zaman uygulanır ve kaynaklara erişimde senkronizasyon ile ilgili ne tür sorunlar vardır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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:

  • Metod düzeyinde senkronizasyon, this düzeyinde senkronizasyon ile eşdeğerdir.
  • Statik metodlar için sınıf-nesne düzeyinde senkronizasyon.
  • Kritik bölgenin alanını en aza indirmek gerekir.

Yanıltıcı Sorular.

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).

Tipik Hatalar ve Anti-Desenler

  • Aşırı "geniş" bir nesne üzerinde senkronizasyon (örneğin, String veya sınıf nesnesi üzerinde)
  • Senkronize blok içerisindeki uzun süreli kod çalıştırma
  • Aynı kaynağa erişimi, synchronized blokları ve senkronize edilmemiş parçalar aracılığıyla karıştırma.

Gerçek Hayattan Örnek

Negatif Durum

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:

  • Basit uygulama

Eksiler:

  • İş parçacıkları arasında beklenmedik veri yarışları
  • Zor tespit edilebilen hatalar

Pozitif Durum

Ortak kaynağı kullanan tüm metodlar, aynı nesne-monitör üzerinde senkronize edilir, kritik bölgenin alanı minimumdur.

Artılar:

  • İş parçacıkları tutarlı verilerle çalışır
  • Minimum kilitleme

Eksiler:

  • Karşılıklı kilitlenmeleri (deadlock) analiz etmek ve sürdürmek daha zor, özellikle senkronize edilmiş nesne sayısı fazla olduğunda.