ProgramlamaBackend geliştirici

Java'da 'volatile' değişken nedir ve 'synchronized'dan nasıl farklıdır? Ne zaman ve neden volatile kullanılmalıdır?

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

Cevap

volatile, bir değişkenin görünürlüğünü tüm iş parçacıkları tarafından garanti eden bir değişken modifikatörüdür. Eğer bir değişken volatile olarak tanımlanmışsa, okunması ve yazılması doğrudan ana bellekten gerçekleşir, iş parçacıklarının yerel önbellekleri bypass edilir. Bu, değerlerin iş parçacığı içinde yerel olarak önbelleğe alınmasını önler.

synchronized, yalnızca görünürlüğü değil, aynı zamanda karşılıklı hariç tutmayı (mutual exclusion) sağlayan bir anahtar kelimedir: yalnızca bir iş parçacığı belirli bir nesne için senkronize bir blok içinde o anda çalışabilir.

volatile değişkenleri, basit bayraklar ve sayaçlar için şöyle kullanmalısınız:

  • Değişkenin değeri önceki durumdan bağımsızsa (örneğin, sayaç bir kez yazılır, birçok kez okunur);
  • Daha karmaşık işlem sırasına ihtiyaç yoksa (check-then-act).

Volatile kullanımı örneği:

class Flag { private volatile boolean running = true; public void stop() { running = false; } public void loop() { while (running) { // ... } } }

Kandırmaca soru

Bir değişkenin artırılmasının atomik olarak sağlanması için volatile kullanılabilir mi?

Cevap: Hayır, volatile işlemlerin atomikliğini sağlamaz. Örneğin, counter++ atomik değildir, counter volatile olarak tanımlansa bile çünkü işlem okuma, değiştirme ve yazma (birden fazla işlem) içerir ve başka bir iş parçacığı tarafından kesilebilir. Atomiklik, synchronized veya java.util.concurrent.atomic paketindeki sınıflar ile sağlanır.

Örnek:

class Counter { private volatile int count = 0; public void increment() { count++; // ATOMİK OLMAYAN İŞLEM! } }

Konuyla ilgili bilgi eksikliğinden kaynaklanan gerçek hata örnekleri


Hikaye

Bir çevrimiçi mağaza projesinde, sipariş işleme iş parçacığının bitiş bayrağı volatile olmadan gerçekleştirilmişti. Sonuç olarak, iş parçacıklarından biri diğer iş parçacığından yapılan değişiklikleri göremediği için sonsuz döngüde "takıldı". Teşhis birkaç gün sürdü.


Hikaye

Finansal sistemde, geliştirici işlem sayacı için volatile int kullandı. Pik yüklerde, işlem sayısı "kaybolmaya" başladı. Sebep — karmaşık artırma işlemlerinde atomikliğin kaybı.


Hikaye

Geliştiriciler, senkronize erişimin sağlanması için volatile kullanmaya çalışarak volatile ve synchronized'ı karıştırdılar, bu da data race ve çok parçacıklı uygulamada zor tespit edilen hatalara yol açtı.