Poin penting tentang volatile:
- Sinkronisasi di Jawa dimungkinkan dengan menggunakan kata kunci
synchronizeddan volatiledan kunci Java .
- Di Jawa, kita tidak bisa memiliki
synchronizedvariabel. Menggunakan synchronizedkata kunci dengan variabel adalah ilegal dan akan menghasilkan kesalahan kompilasi. Alih-alih menggunakan synchronizedvariabel di Jawa, Anda bisa menggunakan volatilevariabel java , yang akan menginstruksikan thread JVM untuk membaca nilai volatilevariabel dari memori utama dan jangan cache secara lokal.
- Jika suatu variabel tidak dibagi di antara beberapa utas, maka tidak perlu menggunakan
volatilekata kunci.
sumber
Contoh penggunaan 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;
}
}
Kami membuat contoh dengan malas pada saat permintaan pertama datang.
Jika kita tidak membuat _instancevariabel volatilemaka Thread yang membuat instance dari Singletontidak dapat berkomunikasi ke thread lain. Jadi jika Thread A membuat Singleton instance dan setelah penciptaan, CPU rusak dll, semua utas lainnya tidak akan dapat melihat nilai _instancebukan nol dan mereka akan percaya itu masih ditugaskan nol.
Mengapa ini terjadi? Karena utas pembaca tidak melakukan penguncian dan sampai utas penulis keluar dari blok yang disinkronkan, memori tidak akan disinkronkan dan nilai _instancetidak akan diperbarui di memori utama. Dengan kata kunci Volatile di Java, ini ditangani oleh Java sendiri dan pembaruan tersebut akan terlihat oleh semua utas pembaca.
Kesimpulan : volatilekata kunci juga digunakan untuk mengkomunikasikan konten memori antara utas.
Contoh penggunaan tanpa volatile:
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;
}
Kode di atas tidak aman untuk thread. Meskipun memeriksa nilai instance sekali lagi di dalam blok yang disinkronkan (untuk alasan kinerja), kompiler JIT dapat mengatur ulang bytecode sedemikian rupa sehingga referensi ke instance diatur sebelum konstruktor menyelesaikan eksekusi. Ini berarti metode getInstance () mengembalikan objek yang mungkin belum diinisialisasi sepenuhnya. Untuk membuat kode-aman, kata kunci volatile dapat digunakan sejak Java 5 untuk variabel instan. Variabel yang ditandai sebagai volatil hanya dapat dilihat oleh utas lainnya setelah konstruktor objek telah menyelesaikan eksekusi sepenuhnya.
Sumber

volatilepenggunaan di Jawa :
Iterator gagal-cepat biasanya diimplementasikan menggunakan volatilepenghitung pada objek daftar.
- Ketika daftar diperbarui, penghitung bertambah.
- Ketika sebuah
Iteratordibuat, nilai saat ini dari penghitung tertanam di Iteratorobjek.
- Ketika
Iteratoroperasi dilakukan, metode ini membandingkan dua nilai penghitung dan melempar a ConcurrentModificationExceptionjika mereka berbeda.
Implementasi iterator gagal-aman biasanya ringan. Mereka biasanya mengandalkan properti dari struktur data implementasi daftar tertentu. Tidak ada pola umum.
volatileyang datang dengan Java Memory Model baru yang didefinisikan dalam JSR 133: bahwa ketika sebuah thread membaca sebuahvolatilevariabel, ia melihat tidak hanya nilai yang terakhir ditulis untuknya oleh beberapa thread lain, tetapi juga semua yang lain menulis ke variabel lain yang terlihat di utas lainnya pada saatvolatilepenulisan. Lihat jawaban ini dan referensi ini .