Atomic Variables in Java with Examples

In mutithreading, 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.

  1. set(int value): Sets to the given value
  2. get(): Gets the current value
  3. lazySet(int value): Eventually sets to the given value
  4. compareAndSet(int expect, int update): Atomically sets the value to the given updated value if the current value == the expected value
  5. addAndGet(int delta): Atomically adds the given value to the current value
  6. decrementAndGet(): Atomically decrements by one the current value

Example:

// Atomic Variable
AtomicInteger var;

Need for Atomic Variable

Consider the below example:



filter_none

edit
close

play_arrow

link
brightness_4
code

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);
    }
}

chevron_right


Output:

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.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    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);
        }
    }

    chevron_right

    
    

    Output:

    200000000
    
  2. Using Atomic variable:
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    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);
        }
    }

    chevron_right

    
    

    Output:

    200000000
    

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : NiravTalaviya