synchronized — kritik kod alanlarına güvenli bir erişim sağlamak için kullanılan bir anahtar kelimedir. Ya metoda (örneğin, public synchronized void foo()), ya da bir kod bloğuna (synchronized(obj) { ... }) uygulanabilir. Bir iş parçacığı synchronized bloğuna girdiğinde, nesnenin monitörünü (lock) alır. Monitör meşguldükçe, diğer iş parçacıkları aynı nesneyi monitör olarak kullanan başka bir synchronized bloğuna giremez.
Özellikler:
this, statik bir nesne (örneğin, sınıf) veya rastgele bir nesne üzerinde senkronize olabilirsiniz.public class Counter { private int count; private final Object lock = new Object(); // özel nesne public void increment() { synchronized(lock) { count++; } } } }
Neden özel bir kilit kullanmak daha iyidir? Çünkü eğer halka açık bir nesne (örneğin, this ya da genel bir dize) üzerinde senkronize olursanız, dış kod bu monitörü de alabilir; bu da deadlock'lara veya hatalı çalışmalara yol açabilir.
Soru: Eğer sabit bir değere sahip bir String nesnesi üzerinde senkronize olursanız ne olur?
Cevap: Java'da dizeler interner ve aynı literallere sahip nesneler aynı nesnelerdir. Eğer synchronized("lock") şeklindeki bir dize üzerinde senkronize olursanız, aynı literali kullanan başka bir kodla karşılaşma riski taşır; bu da programın tamamen farklı bölümleri arasında beklenmedik bir blokaj yaratır.
synchronized("LOCK") { ... }
Hikaye
Çok iş parçacıklı bir ticaret sisteminde senkronizasyon için halka açık nesneler kullanıldı ve dış kod bu kilidi aldı; bu da farklı modüller arasında geçici deadlock'lara ve borsada duraklamalara yol açtı.
Hikaye
Genç bir geliştirici, koleksiyon üzerindeki erişimi bir dize literali ile senkronize etti. Kodun başka bir kısmı da aynı değere sahip bir dize ile senkronize oldu. Bu iş parçacıkları, birbirinin ardına sıraya girdi ve iş mantığında keskin bir yavaşlamaya neden oldu.
Hikaye
Senkronizasyon için her seferinde yeni bir nesne seçildi:
synchronized(new Object()) { ... }. Sonuç olarak, senkronizasyon hiç çalışmadı ve verilere aynı anda farklı iş parçacıkları erişti. Bu, yalnızca yük testi sırasında fark edildi.