volatil (Referensi C#)

Kata volatile kunci menunjukkan bahwa bidang mungkin dimodifikasi oleh beberapa utas yang dijalankan secara bersamaan. Pengkompilasi, sistem runtime, dan bahkan perangkat keras dapat mengatur ulang baca dan tulis ke lokasi memori karena alasan performa. Bidang yang dideklarasikan dikecualikan volatile dari jenis pengoptimalan tertentu. Tidak ada jaminan dari satu urutan total penulisan volatil seperti yang terlihat dari semua utas eksekusi. Untuk informasi selengkapnya, lihat Volatile kelas.

Catatan

Pada sistem multiprosesor, operasi baca volatil tidak menjamin untuk mendapatkan nilai terbaru yang ditulis ke lokasi memori tersebut oleh prosesor apa pun. Demikian pula, operasi penulisan volatil tidak menjamin bahwa nilai yang ditulis akan segera terlihat oleh prosesor lain.

Kata volatile kunci dapat diterapkan ke bidang jenis ini:

  • Jenis referensi.
  • Jenis penunjuk (dalam konteks yang tidak aman). Perhatikan bahwa meskipun penunjuk itu sendiri dapat volatil, objek yang ditujukannya tidak dapat. Dengan kata lain, Anda tidak dapat mendeklarasikan "pointer to volatile."
  • Jenis simpel seperti sbyte, byte, short, ushort, int, uint, char, float, dan bool.
  • Jenis enum dengan salah satu jenis dasar berikut: byte, sbyte, short, ushort, int, atau uint.
  • Parameter jenis generik yang dikenal sebagai jenis referensi.
  • IntPtr dan UIntPtr.

Jenis lain, termasuk double dan long, tidak dapat ditandai volatile karena membaca dan menulis ke bidang dari jenis tersebut tidak dapat dijamin sebagai atomik. Untuk melindungi akses multi-utas ke jenis bidang tersebut Interlocked, gunakan anggota kelas atau lindungi akses menggunakan pernyataan lock.

Kata volatile kunci hanya dapat diterapkan ke bidang class atau struct. Variabel lokal tidak dapat dideklarasikan volatile.

Contoh

Contoh berikut menunjukkan cara mendeklarasikan variabel bidang publik sebagai volatile.

class VolatileTest
{
    public volatile int sharedStorage;

    public void Test(int i)
    {
        sharedStorage = i;
    }
}

Contoh berikut menunjukkan bagaimana utas tambahan atau pekerja dapat dibuat dan digunakan untuk melakukan pemrosesan secara paralel dengan utas utama. Untuk informasi selengkapnya tentang multithreading, lihat Utas Terkelola.

public class Worker
{
    // This method is called when the thread is started.
    public void DoWork()
    {
        bool work = false;
        while (!_shouldStop)
        {
            work = !work; // simulate some work
        }
        Console.WriteLine("Worker thread: terminating gracefully.");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Keyword volatile is used as a hint to the compiler that this data
    // member is accessed by multiple threads.
    private volatile bool _shouldStop;
}

public class WorkerThreadExample
{
    public static void Main()
    {
        // Create the worker thread object. This does not start the thread.
        Worker workerObject = new Worker();
        Thread workerThread = new Thread(workerObject.DoWork);

        // Start the worker thread.
        workerThread.Start();
        Console.WriteLine("Main thread: starting worker thread...");

        // Loop until the worker thread activates.
        while (!workerThread.IsAlive)
            ;

        // Put the main thread to sleep for 500 milliseconds to
        // allow the worker thread to do some work.
        Thread.Sleep(500);

        // Request that the worker thread stop itself.
        workerObject.RequestStop();

        // Use the Thread.Join method to block the current thread
        // until the object's thread terminates.
        workerThread.Join();
        Console.WriteLine("Main thread: worker thread has terminated.");
    }
    // Sample output:
    // Main thread: starting worker thread...
    // Worker thread: terminating gracefully.
    // Main thread: worker thread has terminated.
}

Dengan pengubah volatile ditambahkan ke deklarasi _shouldStop di tempat, Anda akan selalu mendapatkan hasil yang sama (mirip dengan kutipan yang ditampilkan dalam kode sebelumnya). Namun, tanpa pengubah itu _shouldStop pada anggota, perilaku tersebut tidak dapat diprediksi. Metode ini DoWork dapat mengoptimalkan akses anggota, yang mengakibatkan pembacaan data kedaluarsa. Karena sifat pemrograman multi-utas, jumlah bacaan kedaluarsa tidak dapat diprediksi. Eksekusi program yang berbeda akan menghasilkan hasil yang agak berbeda.

Spesifikasi bahasa C#

Untuk informasi selengkapnya, lihat Spesifikasi Bahasa C#. Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.

Lihat juga