Dalam pemrosesan konkurensi Java Thread, ada banyak kebingungan dalam penggunaan kata kunci yang mudah menguap. Saya pikir menggunakan kata kunci ini dapat membuat semuanya berjalan dengan baik saat menggunakan pemrosesan konkurensi multi-threaded.
Bahasa Java mendukung multi-threading. Untuk menyelesaikan masalah konkurensi utas, blok sinkron dan mekanisme kata kunci yang mudah menguap diperkenalkan di dalam bahasa.
disinkronkan
Setiap orang terbiasa dengan blok yang disinkronkan, dan mereka diimplementasikan melalui kata kunci yang disinkronkan. Dengan pernyataan yang disinkronkan dan blok, hanya satu utas yang dapat menggunakannya secara bersamaan saat mengakses multi-thread.
Metode yang dimodifikasi atau blok kode yang disinkronkan.
tidak stabil
Untuk variabel yang dimodifikasi dengan volatil, utas akan membaca nilai variabel yang paling dimodifikasi setiap kali menggunakan variabel. Volatile mudah disalahgunakan dan digunakan untuk operasi atom.
Mari kita lihat contoh di bawah ini. Kami menerapkan penghitung. Setiap kali utas dimulai, metode Counter Inc akan dipanggil untuk menambahkan satu ke konter.
Lingkungan Eksekusi - Versi JDK: JDK1.6.0_31, Memori: 3G CPU: X86 2.4G
counter kelas publik {public static int count = 0; public static void inc () {// penundaan di sini adalah 1 milidetik, membuat hasilnya jelas coba {thread.sleep (1);} catch (interruptedException e) {} count ++;} public static main (string [] args) {// start 1000 threads i threads i thread yang sama, 0;Hasil Menjalankan: Counter.Count = 995
Hasil operasi yang sebenarnya mungkin berbeda setiap saat. Hasil mesin adalah: menjalankan hasil: counter.count = 995. Dapat dilihat bahwa dalam lingkungan multi-threaded, hitungan tidak mengharapkan hasilnya 1000.
Banyak orang berpikir bahwa ini adalah masalah konkurensi multi-utas. Anda hanya perlu menambahkan volatile sebelum jumlah variabel untuk menghindari masalah ini. Kemudian kami memodifikasi kode untuk melihat apakah hasilnya memenuhi harapan kami.
Counter kelas publik {public volatile static int count = 0; public static void inc () {// penundaan di sini adalah 1 milidetik, membuat hasilnya jelas coba {thread.sleep (1);} catch (interruptedException e) {} count ++;} public static main main (string [] args) {//start muint i = 0; i <1000;Hasil Menjalankan: Counter.Count = 992
Hasil operasi masih belum 1000 seperti yang kami harapkan. Mari kita analisis alasan di bawah ini
Dalam artikel koleksi sampah Java, alokasi memori pada saat JVM dijelaskan. Salah satu area memori adalah tumpukan mesin virtual JVM, dan setiap utas memiliki tumpukan utas saat berjalan.
Tumpukan utas menyimpan informasi nilai variabel selama runtime utas. Saat utas mengakses nilai objek tertentu, pertama -tama temukan nilai variabel yang sesuai dengan memori heap melalui referensi objek, dan kemudian letakkan memori heap
Nilai spesifik dari variabel dimuat ke dalam memori lokal utas dan salinan variabel dibuat. Setelah itu, utas tidak lagi memiliki hubungan dengan nilai variabel objek dalam memori heap, tetapi secara langsung memodifikasi nilai variabel salin.
Pada saat tertentu setelah modifikasi (sebelum utas keluar), nilai salinan variabel utas secara otomatis ditulis kembali ke variabel objek dalam heap. Dengan cara ini nilai objek di tumpukan akan berubah. Gambar berikut
Baca dan Muat Variabel Salin Dari Memori Utama ke Memori Kerja Saat Ini
Gunakan dan Tetapkan Kode Etek untuk Mengubah Nilai Variabel Bersama
Simpan dan Tulis Refresh Konten Terkait Memori Utama dengan Data Memori Kerja
di mana penggunaan dan penetapan dapat muncul beberapa kali
Namun, operasi ini bukan atom, yaitu, setelah beban baca, jika variabel jumlah memori utama dimodifikasi, nilai dalam memori kerja utas tidak akan menyebabkan perubahan yang sesuai karena telah dimuat, sehingga hasil yang dihitung akan berbeda dari yang diharapkan.
Untuk variabel yang dimodifikasi dengan volatile, mesin virtual JVM hanya memastikan bahwa nilai yang dimuat dari memori utama ke memori yang berfungsi adalah yang terbaru adalah yang terbaru
Misalnya, jika utas 1 dan utas 2 melakukan operasi baca dan beban, dan temukan bahwa nilai jumlah dalam memori utama adalah 5, maka nilai terbaru akan dimuat
Setelah jumlah tumpukan dimodifikasi dalam utas 1, itu akan ditulis ke dalam memori utama, dan variabel hitungan dalam memori utama akan menjadi 6.
Karena Thread 2 telah melakukan operasi baca dan beban, nilai variabel dari jumlah memori utama juga akan diperbarui menjadi 6 setelah operasi.
Hal ini menyebabkan konkurensi terjadi setelah dua utas dimodifikasi dengan kata kunci yang mudah menguap dalam waktu.
Di atas adalah arti kata kunci yang mudah menguap di Java yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!