Apakah benar mengatakan bahwa itu static
berarti satu salinan nilai untuk semua objek dan volatile
berarti satu salinan nilai untuk semua utas?
Pokoknya static
nilai variabel juga akan menjadi satu nilai untuk semua utas, lalu mengapa kita harus memilihnya volatile
?
Jawaban:
Mendeklarasikan variabel statis di Jawa, berarti hanya akan ada satu salinan, tidak peduli berapa banyak objek kelas yang dibuat. Variabel akan dapat diakses bahkan tanpa
Objects
dibuat sama sekali. Namun, utas mungkin memiliki nilai cached lokal untuknya.Ketika suatu variabel volatile dan tidak statis , akan ada satu variabel untuk masing-masing
Object
. Jadi, di permukaan sepertinya tidak ada perbedaan dari variabel normal tetapi sama sekali berbeda dari statis . Namun, bahkan denganObject
bidang, utas dapat menembolok nilai variabel secara lokal.Ini berarti bahwa jika dua utas memperbarui variabel dari Obyek yang sama secara bersamaan, dan variabel tidak dinyatakan volatil, mungkin ada kasus di mana salah satu utas memiliki cache dalam nilai lama.
Bahkan jika Anda mengakses nilai statis melalui beberapa utas, setiap utas dapat memiliki salinan dalam tembolok lokal! Untuk menghindari ini, Anda dapat mendeklarasikan variabel sebagai volatile statis dan ini akan memaksa utas untuk membaca setiap kali nilai global.
Namun, volatile bukanlah pengganti sinkronisasi yang tepat!
Misalnya:
Menjalankan
concurrentMethodWrong
secara bersamaan berkali-kali dapat menyebabkan nilai akhir counter berbeda dari nol!Untuk mengatasi masalah, Anda harus menerapkan kunci:
Atau gunakan
AtomicInteger
kelas.sumber
Perbedaan Antara Statis dan Volatil:
Variabel Statis : Jika dua Thread (misalkan
t1
dant2
) mengakses objek yang sama dan memperbarui variabel yang dinyatakan sebagai statis maka itu berartit1
dant2
dapat membuat salinan lokal mereka sendiri dari objek yang sama (termasuk variabel statis) di cache masing-masing, jadi perbarui dibuat oleht1
ke variabel statis di cache lokal tidak akan tercermin dalam variabel statis untukt2
cache.Variabel statis digunakan dalam konteks Objek di mana pembaruan yang dibuat oleh satu objek akan mencerminkan semua objek lain dari kelas yang sama tetapi tidak dalam konteks Thread di mana pembaruan satu thread ke variabel statis akan mencerminkan perubahan segera ke semua utas (dalam cache lokal mereka).
Variabel yang mudah menguap : Jika dua Threads (kira
t1
dant2
) mengakses objek yang sama dan memperbarui variabel yang dinyatakan sebagai volatile maka itu berartit1
dant2
dapat membuat cache lokal mereka sendiri Objek kecuali variabel yang dinyatakan sebagai stabil . Jadi variabel volatil hanya akan memiliki satu salinan utama yang akan diperbarui oleh utas berbeda dan pembaruan yang dibuat oleh satu utas ke variabel volatil akan segera mencerminkan ke utas lainnya.sumber
volatile
variabel dapat dibagi di antara cache CPU yang berbeda. Ini tidak menimbulkan masalah karena cache menegosiasikan kepemilikan eksklusif dari baris cache sebelum memodifikasinya.Selain jawaban lain, saya ingin menambahkan satu gambar untuk itu (gambar membuat mudah dimengerti)
static
variabel dapat di-cache untuk masing-masing utas. Di lingkungan multi-utas jika satu utas mengubah data yang di-cache, yang mungkin tidak mencerminkan utas lainnya karena mereka memiliki salinannya .volatile
deklarasi memastikan bahwa utas tidak akan menyimpan data dan hanya menggunakan salinan yang dibagikan .sumber gambar
sumber
Saya berpikir
static
danvolatile
tidak memiliki hubungan sama sekali. Saya sarankan Anda membaca tutorial java untuk memahami Akses Atom , dan mengapa menggunakan akses atom, memahami apa yang disisipkan , Anda akan menemukan jawabannya.sumber
Secara sederhana,
static :
static
variabel dikaitkan dengan kelas , bukan dengan objek apa pun . Setiap instance kelas membagikan variabel kelas, yang berada di satu lokasi tetap dalam memorivolatile : Kata kunci ini berlaku untuk variabel kelas dan instance .
Silahkan lihat pada ini artikel dengan
Javin Paul
memahami variabel volatile dalam cara yang lebih baik.Dengan tidak adanya
volatile
kata kunci, nilai variabel di setiap tumpukan thread mungkin berbeda. Dengan membuat variabel sebagaivolatile
, semua utas akan mendapatkan nilai yang sama dalam memori kerja dan kesalahan konsistensi memori telah dihindari.Di sini istilahnya
variable
dapat berupastatic
variabel (kelas) atau variabelinstance
(objek).Mengenai kueri Anda:
Jika saya perlu
instance
variabel dalam aplikasi saya, saya tidak bisa menggunakanstatic
variabel. Bahkan dalam kasusstatic
variabel, konsistensi tidak dijamin karena Thread cache seperti yang ditunjukkan pada diagram.Menggunakan
volatile
variabel mengurangi risiko kesalahan konsistensi memori, karena setiap penulisan ke variabel volatil membentuk hubungan yang terjadi sebelum dengan membaca selanjutnya dari variabel yang sama. Ini berarti bahwa perubahan ke variabel volatil selalu terlihat oleh utas lainnya.Menggunakan akses variabel atom sederhana lebih efisien daripada mengakses variabel-variabel ini melalui kode yang disinkronkan
Beberapa kelas dalam
java.util.concurrent
paket menyediakan metode atom yang tidak bergantung pada sinkronisasi.Lihat artikel kontrol konkurensi tingkat tinggi ini untuk detail lebih lanjut.
Terutama melihat variabel Atom .
Pertanyaan SE terkait:
Volatile Vs Atomic
Volatile boolean vs AtomicBoolean
Perbedaan antara volatile dan disinkronkan di Jawa
sumber
volatile
sebelumnya, tetapi, jawaban ini memperjelas banyak bagi saya mengapa saya masih perlu menggunakanvolatile
denganstatic
variabel.akses nilai variabel volatile akan langsung dari memori utama. Ini harus digunakan hanya dalam lingkungan multi-threading. variabel statis akan dimuat satu kali. Jika digunakan dalam lingkungan utas tunggal, bahkan jika salinan variabel akan diperbarui dan tidak akan ada salahnya mengaksesnya karena hanya ada satu utas.
Sekarang jika variabel statis digunakan dalam lingkungan multi-threading maka akan ada masalah jika seseorang mengharapkan hasil yang diinginkan darinya. Karena setiap utas memiliki salinannya sendiri maka setiap kenaikan atau penurunan pada variabel statis dari satu utas mungkin tidak tercermin dalam utas lainnya.
jika seseorang mengharapkan hasil yang diinginkan dari variabel statis kemudian gunakan volatile dengan statis dalam multi-threading maka semuanya akan teratasi.
sumber
Tidak yakin variabel statis di-cache di memori lokal thread atau TIDAK. Tetapi ketika saya mengeksekusi dua utas (T1, T2) mengakses objek yang sama (obj) dan ketika pembaruan yang dilakukan oleh utas T1 ke variabel statis itu tercermin di T2.
sumber
Jika kita mendeklarasikan variabel sebagai statis, hanya akan ada satu salinan variabel. Jadi, setiap kali thread berbeda mengakses variabel itu, hanya akan ada satu nilai akhir untuk variabel (karena hanya ada satu lokasi memori yang dialokasikan untuk variabel).
Jika suatu variabel dinyatakan volatil, semua utas akan memiliki salinan variabel sendiri tetapi nilainya diambil dari memori utama. Jadi, nilai variabel di semua utas akan sama.
Jadi, dalam kedua kasus, titik utama adalah bahwa nilai variabel sama di semua utas.
sumber