Atomic Variables in Java with Examples - GeeksforGeeks

10 Jul, 2021
In multithreading, the shared entity mostly leads to a problem when concurrency is incorporated. A shared entity such as, mutable object or variable, might be changed, which may result in the inconsistency of the program or database. So, it becomes crucial to deal with the shared entity while accessed concurrently. An atomic variable can be one of the alternatives in such a scenario. 
Java provides atomic classes such as AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference. Objects of these classes represent the atomic variable of int, long, boolean, and object reference respectively. These classes contain the following methods.
set(int value): Sets to the given valueget(): Gets the current valuelazySet(int value): Eventually sets to the given valuecompareAndSet(int expect, int update): Atomically sets the value to the given updated value if the current value == the expected valueaddAndGet(int delta): Atomically adds the given value to the current valuedecrementAndGet(): Atomically decrements by one the current value
set(int value): Sets to the given value
get(): Gets the current value
lazySet(int value): Eventually sets to the given value
compareAndSet(int expect, int update): Atomically sets the value to the given updated value if the current value == the expected value
addAndGet(int delta): Atomically adds the given value to the current value
decrementAndGet(): Atomically decrements by one the current value
Example:  
// Atomic Variable
AtomicInteger var;
Need for Atomic VariableConsider the below example:
Java
class Counter extends Thread {     // Counter Variable    int count = 0;     // method which would be called upon    // the start of execution of a thread    public void run()    {        int max = 1_000_00_000;         // incrementing counter        // total of max times        for (int i = 0; i < max; i++) {            count++;        }    }} public class UnSafeCounter {    public static void main(String[] args)        throws InterruptedException    {        // Instance of Counter Class        Counter c = new Counter();         // Defining Two different threads        Thread first = new Thread(c, "First");        Thread second = new Thread(c, "Second");         // Threads start executing        first.start();        second.start();         // main thread will wait for        // both threads to get completed        first.join();        second.join();         // Printing final value of count variable        System.out.println(c.count);    }}
137754082
 
In a single thread environment, the above-mentioned class will give the expected result only. But when a multithreaded environment is concerned, it may lead to inconsistent results. It happens because updating “var” is done in three steps: Reading, updating, and writing. If two or more threads try to update the value at the same time, then it may not update properly.
This issue can be solved using Lock and Synchronization, but not efficiently. 
1. Using lock analogy or synchronization: Synchronization or Locking can solve our problem, but it compromises time efficiency or performance. First, it mandates resource and thread scheduler to control lock. Second, when multiple threads attempt to acquire a lock, only one of them wins, rest are suspended or blocked. Suspending or blocking of threads can have a huge impact on performance.
Java
import java.io.*;import java.util.concurrent.locks.*; class Counter extends Thread {     // Counter Variable    int count = 0;     // method which would be called upon    // the start of execution of a thread    public synchronized void run()    {         int max = 1_000_00_000;         // incrementing counter total of max times        for (int i = 0; i < max; i++) {            count++;        }    }} public class SynchronizedCounter {    public static void main(String[] args)        throws InterruptedException    {        // Instance of Counter Class        Counter c = new Counter();         // Defining Two different threads        Thread first = new Thread(c, "First");        Thread second = new Thread(c, "Second");         // Threads start executing        first.start();        second.start();         // main thread will wait for both        // threads to complete execution        first.join();        second.join();         // Printing final value of count variable        System.out.println(c.count);    }}
200000000
 
2. Using Atomic variable: 
Java
import java.util.concurrent.atomic.AtomicInteger; class Counter extends Thread {     // Atomic counter Variable    AtomicInteger count;     // Constructor of class    Counter()    {        count = new AtomicInteger();    }     // method which would be called upon    // the start of execution of a thread    public void run()    {         int max = 1_000_00_000;         // incrementing counter total of max times        for (int i = 0; i < max; i++) {            count.addAndGet(1);        }    }} public class AtomicCounter {    public static void main(String[] args)        throws InterruptedException    {        // Instance of Counter Class        Counter c = new Counter();         // Defining Two different threads        Thread first = new Thread(c, "First");        Thread second = new Thread(c, "Second");         // Threads start executing        first.start();        second.start();         // main thread will wait for both        // threads to complete execution        first.join();        second.join();         // Printing final value of count variable        System.out.println(c.count);    }}
200000000
 
 
 
NiravTalaviya
sumitgumber28
Java-Multithreading
Java-util-concurrent-atomic package
DBMS
Java
Java Programs
Java
DBMS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
CTE in SQL
SQL Interview Questions
SQL Trigger | Student Database
Introduction of B-Tree
Difference between Clustered and Non-clustered index
Arrays in Java
Split() String method in Java with examples
For-each loop in Java
Object Oriented Programming (OOPs) Concept in Java
Reverse a string in Java