Tuesday 7 December 2021

volatile reference vs Atomic references defined in java.util.concurrent.atomic package?

What is volatile?

When a variable is defined using volatile modifier, it is guaranteeing that it will not be cached by threads and threads will see the updated value immediately. Without volatile, readers could see some non-updated value.

 

Let’s see it with an example.

VolatileEx.java 

package com.sample.app.threads;

public class VolatileEx extends Thread {
	boolean flag = true;

	public void run() {
		while (flag) {
		}
		System.out.println("Came out of the loop");
	}

	public static void main(String args[]) throws Exception {
		VolatileEx t1 = new VolatileEx();
		t1.start();
		Thread.sleep(1000);
		t1.flag = false;
		System.out.println("Flag is set to " + t1.flag);
	}
}

 

When you ran above application, program goes to infinite loop. Even you set the flag to false, thread keeps using its local copy of the variable flag ( which is true). This problem is solved by volatile keyword.  

 

Define the variable flag using volatile modifier.

volatile boolean flag = true;

 

VolatileEx.java

package com.sample.app.threads;

public class VolatileEx extends Thread {
	volatile boolean flag = true;

	public void run() {
		while (flag) {
		}
		System.out.println("Came out of the loop");
	}

	public static void main(String args[]) throws Exception {
		VolatileEx t1 = new VolatileEx();
		t1.start();
		Thread.sleep(1000);
		t1.flag = false;
		System.out.println("Flag is set to " + t1.flag);
	}
}

 

Output

Came out of the loop
Flag is set to false

Atomic references

java.util.concurrent.atomic package provides a small toolkit of classes that support lock-free thread-safe programming on single variables.

 

From the Java documentation (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/atomic/package-summary.html), I do not see any difference between volatile and atomic references. AtomicReference get and set has the same Java Memory model semantics as a volatile field.

 

If you look at the code of AtomicReference, it internally use a volatile variable.

public class AtomicReference<V> implements java.io.Serializable {

    private volatile V value;

    .......
    .......
}

When to choose what?

If your use case is simple set and get operations, then you can go for volatile modifier. But if you want to have additional CAS (compare-and-swap) functionality, then you can go for atomic references. In computer science, compare-and-swap (CAS) is an atomic instruction used in multithreading to achieve synchronization. It compares the contents of a memory location with a given value and, only if they are the same, modifies the contents of that memory location to a new given value.

 

CASDemo.java

package com.sample.app.threads;

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {
    
    public static void main(String args[]) {
        AtomicInteger atomicInteger = new AtomicInteger(10);
        
        System.out.println("value " + atomicInteger.get());
        
        if(atomicInteger.compareAndSet(10, 21)) {
            System.out.println("\nValue updated successfully!!!!");
            System.out.println("value " + atomicInteger.get());
        }else {
            System.out.println("\nValue is not updated successfully!!!!");
            System.out.println("value " + atomicInteger.get());
        }
        
        if(atomicInteger.compareAndSet(10, 21)) {
            System.out.println("\nValue updated successfully!!!!");
            System.out.println("value " + atomicInteger.get());
        }else {
            System.out.println("\nValue is not updated successfully!!!!");
            System.out.println("value " + atomicInteger.get());
        }
    }

}

Output

value 10

Value updated successfully!!!!
value 21

Value is not updated successfully!!!!
value 21





You may like

Interview Questions

Java: How to replace a value in ArrayList or LinkedList

Why do we declare logger with static and final?

How to check the type of a variable in Java?

Set a system property in command line

How to get the capacity of ArrayList in Java?

No comments:

Post a Comment