"Hai, Amigo!"

"Hai, Elli!"

"Saya ingin memberi tahu Anda tentang pengubah volatil. Apakah Anda tahu apa itu?"

"Ada hubungannya dengan benang. Aku tidak ingat persisnya."

"Kalau begitu dengarkan. Ini beberapa detail teknis untuk Anda:"

"Komputer memiliki dua jenis memori: memori global (biasa) dan memori yang terpasang di dalam prosesor. Memori prosesor yang terpasang dibagi menjadi register, cache tingkat pertama (L1), cache tingkat kedua (L2), dan tingkat ketiga (L3)."

"Jenis memori ini memiliki kecepatan yang berbeda. Memori tercepat dan terkecil adalah register, lalu cache prosesor (L1, L2, L3), dan terakhir memori global (paling lambat)."

"Memori global dan cache prosesor beroperasi pada kecepatan yang sangat berbeda, sehingga mesin Java memungkinkan setiap utas untuk menyimpan variabel yang paling sering digunakan dalam memori utas lokal (dalam cache prosesor)."

"Bisakah proses ini entah bagaimana dikendalikan?"

"Tidak juga. Semua pekerjaan dilakukan oleh mesin Java. Sangat cerdas dalam mengoptimalkan kinerja."

"Tapi inilah mengapa saya memberi tahu Anda ini. Ada satu masalah kecil. Ketika dua utas bekerja dengan variabel yang sama, masing-masing dapat menyimpan salinan di cache lokalnya sendiri. Dan kemudian satu utas mungkin mengubah variabel, tetapi yang kedua mungkin tidak melihat perubahannya, karena masih bekerja dengan salinan variabelnya sendiri."

"Nah, lalu apa yang bisa dilakukan?"

"Pembuat Java menyediakan kata kunci khusus untuk situasi ini: volatil. Jika sebuah variabel diakses dari utas yang berbeda, Anda perlu menandainya dengan pengubah volatil, sehingga mesin Java tidak memasukkannya ke dalam cache. Biasanya seperti ini terlihat:"

public volatile int count = 0;

"Oh, aku ingat. Kamu sudah menyebutkan ini. Aku sudah mengetahuinya."

"Tentu saja. Tapi kamu mengingatnya hanya ketika aku memberitahumu."

"Eh, yah, aku agak lupa."

"Pengulangan adalah ibu dari pembelajaran!"

"Berikut adalah beberapa fakta baru tentang pengubah volatil. Pengubah volatil hanya menjamin bahwa variabel akan dibaca dan ditulis dengan aman. Itu tidak menjamin bahwa itu akan diubah dengan aman."

"Apa bedanya?"

"Lihatlah bagaimana variabel diubah:"

Kode Apa yang sebenarnya terjadi: Keterangan
count++
register = count;

register = register+1;

count = register;
Langkah 1.
Nilai jumlah variabel disalin dari memori global ke register prosesor.

Langkah 2.
Di dalam prosesor, variabel register bertambah 1.

Langkah 3.
Nilai variabel disalin dari prosesor ke memori global.

"Wah! Jadi, semua variabel diubah hanya di prosesor?"

"Ya."

"Dan nilainya disalin bolak-balik: dari memori ke prosesor dan sebaliknya?"

"Ya."

"Pengubah volatil menjamin bahwa ketika jumlah variabel diakses, itu akan dibaca dari memori (langkah 1). Dan jika utas ingin menetapkan nilai baru, itu pasti akan ada di memori global (langkah 3)."

"Tapi mesin Java tidak menjamin bahwa tidak akan ada peralihan utas antara langkah 1 dan 3."

"Jadi, menambah variabel dengan 1 sebenarnya adalah tiga operasi?"

"Ya."

"Dan jika dua utas secara bersamaan ingin mengeksekusi count++, maka mereka dapat saling mengganggu?"

"Ya, periksalah:"

Utas 1 Utas 2 Hasil
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"Jadi, kamu bisa mengakses variabelnya, tapi mengubahnya tetap berisiko?"

"Yah, kamu bisa mengubahnya, hati-hati ☺"

"Bagaimana?"

" sinkronisasi  adalah sahabat kita."

"Jadi begitu."