Hakkında önemli nokta volatile
:
- Java Senkronizasyon Java anahtar kelimeler kullanarak mümkündür
synchronized
ve volatile
ve kilitler.
- Java'da
synchronized
değişkenimiz olamaz . Kullanılması synchronized
bir değişkene sahip anahtar kelimeyi yasa dışıdır ve derleme hatasına neden olur. synchronized
Java'da değişkeni kullanmak yerine, volatile
JVM iş parçacıklarının değerini okumasını söyleyen java değişkenini kullanabilirsiniz .volatile
ana bellekten değişkenin yerel olarak önbelleğe almasını istemeyen .
- Bir değişken birden fazla evre arasında paylaşılmazsa,
volatile
anahtar kelimeyi kullanmaya gerek yoktur .
kaynak
Örnek kullanım volatile
:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
İlk istek geldiğinde tembel bir şekilde örnek yaratıyoruz.
_instance
Değişkeni yapmazsak volatile
, örneğini oluşturan Evre Singleton
diğer evre ile iletişim kuramaz. Dolayısıyla A İş parçacığı Singleton örneği oluşturuyorsa ve oluşturma işleminden hemen sonra CPU bozulursa, diğer tüm iş parçacıkları_instance
null değil olarak yine de null atandığına inanırlar.
Bu neden oluyor? Okuyucu iş parçacıkları kilitleme yapmadığından ve yazar iş parçacığı senkronize edilmiş bir bloktan çıkıncaya kadar, bellek senkronize edilmeyecek ve değeri _instance
ana bellekte güncellenmeyecektir. Java'daki Volatile anahtar sözcüğüyle bu, Java'nın kendisi tarafından işlenir ve bu güncellemeler tüm okuyucu dizileri tarafından görülebilir.
Sonuç : volatile
anahtar kelime, evreler arasındaki bellek içeriğini iletmek için de kullanılır.
Uçucu olmadan kullanım örneği:
public class Singleton{
private static Singleton _instance; //without volatile variable
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null) _instance = new Singleton();
}
}
return _instance;
}
Yukarıdaki kod iş parçacığı için güvenli değildir. Eşitlenmiş blok içinde örneğin değerini bir kez daha kontrol etmesine rağmen (performans nedenleriyle), JIT derleyicisi, bayt kodunu, kurucu yürütmeyi tamamlamadan önce örneğe yapılan başvurunun ayarlandığı şekilde yeniden düzenleyebilir. Bu, getInstance () yönteminin tamamen başlatılmamış olabilecek bir nesneyi döndürdüğü anlamına gelir. Kodu iş parçacığı açısından güvenli hale getirmek için, değişken değişkeni için Java 5'ten beri geçici anahtar kelime kullanılabilir. Uçucu olarak işaretlenen değişkenler, yalnızca nesnenin kurucusu yürütülmesini tamamladıktan sonra diğer evreler tarafından görülebilir.
Kaynak
volatile
Java'da kullanım :
Hata hızlı yineleyiciler genelliklevolatile
liste nesnesindeki bir sayaç kullanılarak uygulanır .
- Liste güncellendiğinde sayaç artırılır.
- Bir
Iterator
oluşturulduğunda, sayacın geçerli değeri Iterator
nesneye gömülür .
- Bir
Iterator
işlem gerçekleştirildiğinde, yöntem iki sayaç değerini karşılaştırır ve ConcurrentModificationException
farklıysa a atar .
Arıza güvenlikli yineleyicilerin uygulanması tipik olarak hafiftir. Genellikle belirli liste uygulamasının veri yapılarının özelliklerine güvenirler. Genel bir örüntü yoktur.
volatile
JSR 133'te tanımlanan yeni Java Bellek Modeli ile birlikte gelen önemli bir özelliği atlar : bir iş parçacığı birvolatile
değişkeni okuduğunda, yalnızca başka bir iş parçacığının kendisine yazdığı son değeri değil, diğer tüm değişkenlerin devolatile
yazma sırasında o diğer evrede görülebiliyordu . Bkz bu cevabı ve bu referansı .