"Merhaba, Amigo!"

"Merhaba Ellie!"

"Size uçucu düzenleyiciden bahsetmek istiyorum. Bunun ne olduğunu biliyor musunuz?"

"İpliklerle ilgili bir şey. Tam olarak hatırlamıyorum."

"Öyleyse beni dinle. İşte sana bazı teknik detaylar:"

"Bir bilgisayarda iki tür bellek vardır: genel (sıradan) bellek ve işlemcide yerleşik bellek. Yerleşik işlemci belleği, kayıtlara bölünmüştür, birinci düzey önbellek (L1), ikinci düzey önbellek (L2) ve üçüncü seviye (L3)."

"Bu tür belleklerin farklı hızları vardır. En hızlı ve en küçük bellek, yazmaçlardır, ardından işlemci önbelleği (L1, L2, L3) ve son olarak genel bellektir (en yavaş olanı).

"Global bellek ve işlemci önbelleği çok farklı hızlarda çalışır, bu nedenle Java makinesi her iş parçacığının en sık kullanılan değişkenleri yerel iş parçacığı belleğinde (işlemci önbelleğinde) depolamasına izin verir."

"Bu süreç bir şekilde kontrol edilebilir mi?"

"Pek sayılmaz. Tüm işi Java makinesi yapıyor. Performansı optimize etmeye gelince çok akıllı."

"Ama bunu sana bu yüzden söylüyorum. Küçük bir sorun var. İki iş parçacığı aynı değişkenle çalışırken, her biri kendi yerel önbelleğinde bir kopya saklayabilir. Sonra bir iş parçacığı değişkeni değiştirebilir, ama ikincisi değişkenin kendi kopyasıyla çalıştığı için değişikliği göremeyebilir."

"Peki, o zaman ne yapılabilir?"

"Java'nın yaratıcıları bu durum için özel bir anahtar kelime sağladı: volatile. Bir değişkene farklı iş parçacıklarından erişiliyorsa, onu volatile değiştiricisiyle işaretlemeniz gerekir, böylece Java makinesi onu önbelleğe koymaz. Genellikle böyle olur görünüyor:"

public volatile int count = 0;

"Ah, hatırlıyorum. Bundan zaten bahsetmiştin. Bunu zaten biliyorum."

"Tabii ki biliyorsun. Ama bunu ancak sana söylediğimde hatırladın."

"Şey, ben biraz unutmuşum."

"Tekrar, öğrenmenin anasıdır!"

"İşte uçucu değiştirici hakkında birkaç yeni gerçek. Uçucu değiştirici yalnızca değişkenin güvenli bir şekilde okunacağını ve yazılacağını garanti eder. Güvenli bir şekilde değiştirileceğini garanti etmez."

"Fark ne?"

"Bir değişkenin nasıl değiştirildiğine bakın:"

kod Gerçekten ne olur: Tanım
count++
register = count;

register = register+1;

count = register;
Adım 1.
Değişken sayımının değeri, genel bellekten bir işlemci kaydına kopyalanır.

Adım 2.
İşlemcinin içinde, kayıt değişkeni 1 artırılır.

Adım 3.
Değişkenin değeri işlemciden global belleğe kopyalanır.

"Vay be! Yani tüm değişkenler sadece işlemcide mi değişiyor?"

"Evet."

"Ve değerler ileri geri kopyalanıyor: bellekten işlemciye ve geri mi?"

"Evet."

"Uçucu değiştirici, count değişkenine erişildiğinde bunun bellekten okunacağını garanti eder (adım 1). Ve bir iş parçacığı yeni bir değer atamak isterse, kesinlikle genel bellekte olacaktır (adım 3)."

"Ancak Java makinesi, 1. ve 3. adımlar arasında herhangi bir iş parçacığı geçişi olmayacağını garanti etmiyor."

"Yani, değişkeni 1 artırmak aslında üç işlem mi?"

"Evet."

"Ve eğer iki iş parçacığı aynı anda count++'ı yürütmek isterse, o zaman birbirlerine müdahale edebilirler mi?"

"Evet, bak:"

konu 1 Konu 2 Sonuç
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"Yani, değişkene erişebilirsiniz, ancak onu değiştirmek yine de riskli mi?"

"Pekala, değiştirebilirsin, sadece dikkatli ol ☺"

"Nasıl?"

" senkronize  en iyi arkadaşımızdır."

"Anlıyorum."