Apa perbedaan antara metode lazySet
dan ? The dokumentasi tidak memiliki banyak untuk mengatakan tentang :set
AtomicInteger
lazySet
Akhirnya disetel ke nilai yang diberikan.
Tampaknya nilai yang disimpan tidak akan langsung disetel ke nilai yang diinginkan, tetapi akan dijadwalkan untuk disetel di masa mendatang. Tapi, apa kegunaan praktis dari metode ini? Ada contoh?
sumber
Atomic*
cakupan).lazySet dapat digunakan untuk komunikasi antar thread rmw, karena xchg bersifat atomic, sedangkan untuk visibilitas, ketika proses thread penulis mengubah lokasi baris cache, prosesor thread pembaca akan melihatnya di pembacaan berikutnya, karena protokol koherensi cache intel cpu akan menjamin LazySet berfungsi, tetapi baris cache akan diperbarui pada pembacaan berikutnya, sekali lagi, CPU harus cukup modern.
http://sc.tamu.edu/systems/eos/nehalem.pdf Untuk Nehalem yang merupakan platform multi-prosesor, prosesor memiliki kemampuan untuk "mengintip" (menguping) bus alamat untuk akses prosesor lain ke memori sistem dan ke cache internal mereka. Mereka menggunakan kemampuan pengintaian ini untuk menjaga agar cache internal mereka tetap konsisten baik dengan memori sistem maupun dengan cache di prosesor lain yang saling berhubungan. Jika melalui pengintaian, satu prosesor mendeteksi bahwa prosesor lain bermaksud untuk menulis ke lokasi memori yang saat ini telah di-cache dalam status Bersama, prosesor pengintai akan membatalkan blok cache-nya dan memaksanya untuk melakukan pengisian baris cache saat berikutnya mengakses lokasi memori yang sama .
oracle hotspot jdk untuk arsitektur cpu x86->
lazySet == unsafe.putOrderedLong == xchg rw (instruksi asm yang berfungsi sebagai penghalang lunak selama 20 siklus pada nehelem intel cpu)
pada x86 (x86_64) penghalang seperti itu jauh lebih murah dari segi kinerja daripada volatile atau AtomicLong getAndAdd,
Dalam satu produsen, satu skenario antrian konsumen, xchg soft barrier dapat memaksa baris kode sebelum lazySet (urutan + 1) untuk thread produsen terjadi SEBELUM kode thread konsumen yang akan mengkonsumsi (mengerjakan) data baru, tentu saja utas konsumen perlu memeriksa secara atomis bahwa urutan produsen bertambah tepat satu menggunakan bandingkanAndSet (urutan, urutan + 1).
Saya menelusuri setelah kode sumber Hotspot untuk menemukan pemetaan yang tepat dari lazySet ke kode cpp: http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp Unsafe_setOrderedLong -> definisi SET_FIELD_VOLATILE -> OrderAccess: release_store_fence. Untuk x86_64, OrderAccess: release_store_fence didefinisikan sebagai menggunakan instruksi xchg.
Anda dapat melihat bagaimana tepatnya didefinisikan di jdk7 (doug lea bekerja pada beberapa hal baru untuk JDK 8): http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
Anda juga dapat menggunakan hdis untuk membongkar perakitan kode lazySet.
Ada pertanyaan terkait lainnya: Apakah kita membutuhkan mfence saat menggunakan xchg
sumber
Diskusi yang lebih luas tentang asal dan kegunaan lazySet dan putOrdered yang mendasari dapat ditemukan di sini: http://psy-lob-saw.blogspot.co.uk/2012/12/atomiclazyset-is-performance-win-for.html
Untuk meringkas: lazySet adalah penulisan volatile yang lemah dalam arti bahwa ia bertindak sebagai penyimpanan-penyimpanan dan bukan pagar penyimpanan-penyimpanan. Ini bermuara pada lazySet menjadi JIT yang dikompilasi menjadi instruksi MOV yang tidak dapat diurutkan ulang oleh kompilator daripada instruksi yang jauh lebih mahal yang digunakan untuk set volatil.
Saat membaca nilai, Anda selalu berakhir dengan membaca volatile (dengan Atomic * .get () dalam hal apa pun).
lazySet menawarkan kepada satu penulis mekanisme penulisan volatil yang konsisten, yaitu sah bagi satu penulis untuk menggunakan lazySet untuk menaikkan penghitung, beberapa utas yang menaikkan penghitung yang sama harus menyelesaikan penulisan yang bersaing menggunakan CAS, yang persis terjadi di bawah sampul Atomic * untuk incAndGet.
sumber
StoreStore
penghalang, tetapi tidak seorangStoreLoad
?Dari ringkasan paket atomik serentak
lazySet memiliki efek memori saat menulis (menugaskan) variabel volatil kecuali bahwa ia mengizinkan pengurutan ulang dengan tindakan memori berikutnya (tetapi tidak sebelumnya) yang tidak dengan sendirinya memaksakan batasan pengurutan ulang dengan penulisan non-volatil biasa. Di antara konteks penggunaan lainnya, lazySet dapat diterapkan saat meniadakan, demi pengumpulan sampah, referensi yang tidak pernah diakses lagi.
Jika Anda penasaran dengan lazySet maka Anda juga berhutang penjelasan lain kepada diri Anda sendiri
sumber
Berikut adalah pemahaman saya, perbaiki saya jika saya salah: Anda dapat menganggapnya
lazySet()
sebagai "semi" volatile: pada dasarnya ini adalah variabel non-volatile dalam hal membaca oleh utas lain, yaitu nilai yang ditetapkan oleh lazySet mungkin tidak terlihat oleh orang lain benang. Tapi itu menjadi tidak stabil ketika operasi tulis lain terjadi (mungkin dari utas lain). Satu-satunya dampak dari lazySet yang dapat saya bayangkan adalahcompareAndSet
. Jadi jika Anda menggunakanlazySet()
,get()
dari utas lain mungkin masih mendapatkan nilai lama, tetapicompareAndSet()
akan selalu memiliki nilai baru karena ini adalah operasi tulis.sumber
compareAndSet
?Re: mencoba untuk membodohinya -
Anda dapat menganggap ini sebagai cara untuk memperlakukan bidang yang mudah menguap seolah-olah tidak mudah menguap untuk operasi penyimpanan tertentu (misalnya: ref = null;).
Itu tidak sepenuhnya akurat, tetapi seharusnya cukup bahwa Anda dapat membuat keputusan antara "OK, saya benar-benar tidak peduli" dan "Hmm, biarkan saya memikirkannya sebentar".
sumber