Volatile Keyword in Java


In Java, the volatile keyword is used to declare a variable as volatile. When a variable is declared as volatile, it has certain characteristics and guarantees regarding its visibility and ordering of operations. It is primarily used in multithreaded applications to ensure that changes made to the variable are visible to other threads and to prevent certain types of instruction reordering by the compiler and the CPU.

Here are the key points of the volatile keyword:

  1. Visibility: When a variable is declared as volatile, any write to that variable is immediately visible to other threads. This means that changes to the variable are not cached locally by threads, ensuring that all threads see the most recent value.
  2. Atomicity: The volatile keyword guarantees atomicity for read and write operations on the variable. This means that read and write operations on a volatile variable are indivisible, so you won’t get into a situation where one thread reads a partially updated value.
  3. No Locks: Unlike other synchronization mechanisms like synchronized or Locks, volatile does not involve acquiring and releasing locks, which makes it more efficient for simple cases where you only need visibility and atomicity.

Here’s an example of using the volatile keyword:

VolatileExample.java
package org.websparrow;

public class VolatileExample {

    private volatile boolean flag = false;

    public void toggleFlag() {
        flag = !flag;
    }

    public void printFlag() {
        System.out.println("Flag: " + flag);
    }

    public static void main(String[] args) {

        VolatileExample example = new VolatileExample();

        Thread writerThread = new Thread(() -> {
            try {
                Thread.sleep(1000); // Simulate some work
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            example.toggleFlag(); // Change the flag value
            System.out.println("Flag has been changed by the writer thread.");
        });

        Thread readerThread = new Thread(() -> {
            while (!example.flag) {
                // Wait for the flag to change
            }
            example.printFlag(); // Read the flag value
        });

        writerThread.start();
        readerThread.start();
    }
}

In this above example, we have a boolean variable flag marked as volatile. The writer thread changes the value of flag, and the reader thread waits for the flag to change and then reads its value. The use of volatile ensures that the changes made by the writer thread are immediately visible to the reader thread.

Output:

console.log
Flag has been changed by the writer thread.
Flag: true

Note: volatile is useful for simple cases like the one above, it may not be sufficient for more complex synchronization requirements. For more complex scenarios, you may need to use other synchronization mechanisms like synchronized or Locks.

References

  1. Atomic Access- JavaDoc
  2. Java Atomic Variable

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.