Uçucu anahtar kelime, bir değişkenin değerini farklı iş parçacıklarına göre değiştirmek için kullanılır. Ayrıca sınıfların iş parçacığını güvenli hale getirmek için de kullanılır. Bu, birden fazla iş parçacığının bir yöntemi ve sınıfların örneğini aynı anda sorunsuzca kullanabileceği anlamına gelir. Uçucu anahtar kelime ilkel türle veya nesnelerle kullanılabilir.
volatile anahtar sözcüğü değişkenin değerini önbelleğe almaz ve değişkeni her zaman ana bellekten okur. volatile anahtar sözcüğü sınıflarla veya yöntemlerle kullanılamaz. Ancak değişkenlerle birlikte kullanılır. Aynı zamanda görünürlüğü ve düzeni de garanti eder. Derleyicinin kodu yeniden sıralamasını engeller.
Belirli bir cihaz kaydının içeriği herhangi bir zamanda değişebilir, dolayısıyla bu tür erişimlerin derleyici tarafından optimize edilmediğinden emin olmak için uçucu anahtar kelimeye ihtiyacınız vardır.
Örnek
class Test { static int var=5; }
Yukarıdaki örnekte, iki iş parçacığının aynı sınıfta çalıştığını varsayalım. Her iki iş parçacığı, her iş parçacığının kendi var yerel kopyasına sahip olduğu farklı işlemcilerde çalışır. Herhangi bir iş parçacığı değerini değiştirirse, değişiklik ana bellekteki orijinal iş parçacığına yansımayacaktır. Diğer iş parçacığının değiştirilen değerden haberdar olmaması nedeniyle veri tutarsızlığına yol açar.
class Test { static volatile int var =5; }
Yukarıdaki örnekte statik değişkenler tüm nesneler arasında paylaşılan sınıf üyeleridir. Ana bellekte tek kopya bulunmaktadır. Geçici bir değişkenin değeri hiçbir zaman önbellekte saklanmaz. Tüm okuma ve yazma işlemleri ana bellekten ve ana belleğe yapılacaktır.
Ne zaman kullanılmalı?
- Long ve double değişkenlerini otomatik olarak okuyup yazmak istiyorsanız uçucu bir değişken kullanabilirsiniz.
- Java'da senkronizasyon sağlamanın alternatif bir yolu olarak kullanılabilir.
- Yazma işlemi tamamlandıktan sonra tüm okuyucu iş parçacıkları uçucu değişkenin güncellenmiş değerini görecektir. Uçucu anahtar kelimeyi kullanmıyorsanız farklı okuyucu dizisi farklı değerler görebilir.
- Derleyiciye birden fazla iş parçacığının belirli bir ifadeye erişeceğini bildirmek için kullanılır. Derleyicinin herhangi bir yeniden sıralama veya optimizasyon yapmasını engeller.
- Uçucu değişken kullanmıyorsanız, derleyici kodu yeniden düzenleyebilir, ana bellekten okumak yerine uçucu değişkenin önbellek değerini yazmakta serbesttir.
Önemli noktalar
- Volatile anahtar kelimesini değişkenlerle birlikte kullanabilirsiniz. Uçucu anahtar kelimenin sınıflar ve yöntemlerle kullanılması yasa dışıdır.
- Geçici değişkenin değerinin yerel iş parçacığı önbelleğinden değil, her zaman ana bellekten okunacağını garanti eder.
- Değişkeni geçici olarak bildirdiyseniz Okuma ve Yazma işlemleri atomiktir
- Bellek tutarlılığı hatası riskini azaltır.
- Java'daki uçucu değişkene yapılan herhangi bir yazma, aynı değişkenin ardışık okumalarıyla ilişkiden önce bir olay meydana getirir.
- Uçucu değişkenler her zaman diğer iş parçacıkları tarafından görülebilir.
- Bir nesne referansı olan uçucu değişken boş olabilir.
- Bir değişken birden fazla iş parçacığı arasında paylaşılmadığında, bu değişkenle volatile anahtar sözcüğünü kullanmanıza gerek yoktur.
Senkronizasyon ile geçici anahtar kelime arasındaki fark
Uçucu anahtar kelime, senkronize anahtar kelimenin yerine geçmez ancak belirli durumlarda alternatif olarak kullanılabilir. Aşağıdaki farklılıklar vardır:
Geçici Anahtar Kelime | Senkronizasyon Anahtar Kelimesi |
---|---|
Uçucu anahtar kelime bir alan değiştiricidir. | Senkronize anahtar kelime, kod bloklarını ve yöntemlerini değiştirir. |
Uçucu olması durumunda iş parçacığı beklemek için bloke edilemez. | Senkronizasyon durumunda konuların beklemesi engellenebilir. |
İplik performansını artırır. | Senkronize yöntemler iş parçacığı performansını düşürür. |
İş parçacığı belleği ile ana bellek arasında bir seferde bir değişkenin değerini senkronize eder. | İş parçacığı belleği ile ana bellek arasındaki tüm değişkenlerin değerini senkronize eder. |
Geçici alanlar derleyici optimizasyonuna tabi değildir. | Senkronizasyon derleyici optimizasyonuna tabidir. |
Geçici Anahtar Kelime Örneği
Aşağıdaki örnekte sayaç değerini artıran bir sınıf tanımladık. VolatileThread.java'daki run () yöntemi, iş parçacığı yürütülmeye başladığında güncellenmiş değeri ve eski değeri alır. Ana sınıfta thread dizisini tanımlıyoruz.
VolatileData.java
public class VolatileData { private volatile int counter = 0; public int getCounter() { return counter; } public void increaseCounter() { ++counter; //increases the value of counter by 1 } }
VolatileThread.java
VolatileThread.java public class VolatileThread extends Thread { private final VolatileData data; public VolatileThread(VolatileData data) { this.data = data; } @Override public void run() { int oldValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: Old value = ' + oldValue); data.increaseCounter(); int newValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: New value = ' + newValue); } }
VolatileMain.java
public class VolatileMain { private final static int noOfThreads = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); //object of VolatileData class Thread[] threads = new Thread[noOfThreads]; //creating Thread array for(int i = 0; i <noofthreads; ++i) threads[i]="new" volatilethread(volatiledata); for(int i="0;" < noofthreads; threads[i].start(); starts all reader threads threads[i].join(); wait for } pre> <p> <strong>Output:</strong> </p> <pre> [Thread 9]: Old value = 0 [Thread 9]: New value = 1 [Thread 10]: Old value = 1 [Thread 10]: New value = 2 </pre> <hr></noofthreads;>