AtomicInteger in Java

Filed Under: Java

Today we will look into AtomicInteger in Java. Atomic operations are performed in a single unit of task without interference from other operations. Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.

AtomicInteger

AtomicInteger, java atomicinteger, atomic integer

Let’s create a simple multi-threaded program where every thread increments the shared count variable 4 times. So if there are two threads, after they finish count value should be 8.

JavaAtomic.java


package com.journaldev.concurrency;

public class JavaAtomic {

    public static void main(String[] args) throws InterruptedException {

        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }

}

class ProcessingThread implements Runnable {
    private int count;

    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count++;
        }
    }

    public int getCount() {
        return this.count;
    }

    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

If you will run above program, you will notice that count value varies between 5,6,7,8. The reason is because count++ is not an atomic operation. So by the time one threads read it’s value and increment it by one, other thread has read the older value leading to wrong result.

To solve this issue, we will have to make sure that increment operation on count is atomic, we can do that using Synchronization but Java 5 java.util.concurrent.atomic provides wrapper classes for int and long that can be used to achieve this atomic operation without usage of Synchronization.

Java AtomicInteger Example

Here is the updated program that will always output count value as 8 because AtomicInteger method incrementAndGet() atomically increments the current value by one.


package com.journaldev.concurrency;

import java.util.concurrent.atomic.AtomicInteger;

public class JavaAtomic {

    public static void main(String[] args) throws InterruptedException {

        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }
}

class ProcessingThread implements Runnable {
    private AtomicInteger count = new AtomicInteger();

    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count.incrementAndGet();
        }
    }

    public int getCount() {
        return this.count.get();
    }

    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Benefits of using Concurrency classes for atomic operation is that we don’t need to worry about synchronization. This improves code readability and chance of errors are reduced. Also atomic operation concurrency classes are assumed to be more efficient that synchronization which involves locking resources.

Comments

  1. Rakesh Agarwal says:

    Hi Sir,
    I am getting inconsistent result although i am using AtomicInteger,Can you help me out.
    import java.util.concurrent.atomic.AtomicInteger;

    public class ThreadTest implements Runnable {
    AtomicInteger i=new AtomicInteger();
    public static void main(String[] args) {
    Thread test=new Thread(new ThreadTest());
    test.start();
    test.run();

    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    i.incrementAndGet();
    System.out.println(Thread.currentThread().getName() +”: ” + i.get());
    }

    }

    Expected Outup: each time the output should be 1 2

  2. Vimal Panchal says:

    Can we use instead of AtomicInteger, CountDownLatch for the multithread environment?

  3. Prakash says:

    Thanks for the nice and valuable article Pankaj !!!

    Can you share any idea on how to ensure consistency and thread safe for a String shared by multiple threads.
    Or do I need to use any other dataType for TEXT type ???

    Thanks in advance

    1. Pankaj says:

      String is immutable, so it’s thread-safe. You can use it in the multithreaded environment.

  4. Radhika Sharma says:

    Great Job Pankaj . Blogs are very simple and helpful .

  5. ashu says:

    Hello Sir

    I understand the concept but there is one thing I am failing to understand. If i remove the processSomething(i) call, then every time i am getting the count=8. I tried for almost 20 times but every time got perfect 8.
    Can you please explain why

    1. ashu says:

      I think i got the reason, If i increase the loop from 4 to say 5000 then i am get the expected result(somthing between 5000 and 10000). I think 4 is to small a count , whenever a thread will get some cpu time it will be able to increase the counter by 4.

  6. Prashant says:

    I think we need better explanation, not just the syntax on how to use AtomicInteger, its available everywhere else on the internet.

  7. Nitin says:

    This is a wrong explanation u r joining both threads . Did not expect this dumb kind of explanation from such a senior analyst.

    Clear ur concepts first.

    1. Pankaj says:

      Thanks for calling me a senior analyst. And what is the problem with join()? It’s used so that main method finishes after both the threads and we can simulate the problem.

      1. Praneet Pushpal says:

        I think t1.join() will block other threads until t1 is terminated and then t2.join() will block other threads until t2 completes. In this case threads will run sequentially t1 then t2 then main thread.
        So, join should not be there in this explanation. Correct me if I am wrong.

        1. Shuo Zhang says:

          No you didn’t understand join() method. When you add some log in the ProcessingThread like

          System.out.printf(“%s: %d\n”,Thread.currentThread().getName(),this.getCount()) you will understand better;

          1. Yogesh Bombe says:

            You are right.

          2. jeesk says:

            I think that Thread.sleep(i * 1);, So thread main, t1 and t2 are running parallel. .

            if don’t use Thread.sleep(); So t1 and t2 are running order;

    2. Prianc says:

      Clear you concepts first. And before that clear your concepts of how to talk in comments section. knowledge is give and take relationship. Why so angry if you know something.

      1. craig says:

        well said

    3. Ram says:

      He has called the join after issuing the start command on both the threads. The subsequent joins will pause the main thread until t1 and t2 are complete. Why do you think they would be sequential

    4. Swapnil says:

      I don’t see any issue with the example. Thread main, t1 and t2 are running parallel. Check when start() method is called. t1.join() makes main thread to wait for t1’s completion and then t2.join() makes main thread to wait for t2’s completion. It’s not like t1 and t2 are not running parallel. Definitely t1 and t2 are running parallel.
      Very nice Pankaj for this article.

  8. IM says:

    I think the count value going “5,6,7,8” is perfectly acceptable in your first example isn’t it?

    But Yes. I got the concept.

    1. ASHISH JAIN(Technical Consultant) says:

      I think the count value will be always 8.

  9. Wells Lee says:

    it’s very usefully for me ,this is my first time visited this site.The tutorials understandability,thanks a lot.But i didn’t understand how to use Atomic integer class?

  10. Lalita says:

    Good site for java interview preparation. But i didn’t understand why to use Atomic integer class. Can you please provide the scenario where we can use this

  11. sachin says:

    Hi,

    Simply i can modify the program you suggested above for atomic but i haven’t seen any benefit of this atomic variable because in both cases i am getting same result. So can you please provide another example for the same to see what exactly it is..

    package test;

    import java.util.concurrent.atomic.AtomicInteger;

    public class JavaAtomic {

    public static void main(String[] args) throws InterruptedException {

    ProcessingThread pt = new ProcessingThread();

    Thread t1 = new Thread(pt, “t1”);
    Thread t2 = new Thread(pt, “t2”);

    t1.start();
    t2.start();

    t1.join();
    t2.join();

    System.out.println(“Processing count=” + pt.getCount());
    }

    }

    class ProcessingThread implements Runnable {

    // private AtomicInteger count = new AtomicInteger();
    int count = 0;

    @Override
    public void run() {

    // count.incrementAndGet();
    for (int i = 0; i < 4; i++) {
    count++;
    }

    }

    public int getCount() {
    // return this.count.get();
    return count;
    }

    }

    1. Umesh says:

      Yeah its late reply, but will help others.
      try to put a sleep(100) in run method, and run your program 8~10 times again & again, you will get it.
      Also @Pankaj, Thanks a lot for such great tutorials, Journaldev is best among others. Great work

  12. Sorrowfull Blinger says:

    How is atomicity incorporated into the Atomic Integer class? it has to be via locks right ?? Then how is this different from Synchronisation block?

    1. Pankaj says:

      Yes internally it must be using locks but because Java provides guarantee of atomic operations, we don’t need to implement it ourself, this is the plus point.

      1. Prashant says:

        I dont think its using locks since synchronization reduces the throughput of the execution and AtomicIntegers are used in lock-free implementation.

        1. Pallavi says:

          Internally Atomic integer is volatile integer. Through Volatility, it is providing Atmicity.
          Every read and write operation happens from memory,

          1. Deepak D says:

            Not true IMO. Atomic Integers are more Thread Safer than volatile variables. volatile guarantees only the exact value at any point, but does not guarantee thread safety. meaning to say since ++ operation internally involves 2 operations 1 for reading other for doing +1. Using volatile in multi-threaded scenario will result in race condition.
            Explanation : when Thread 1 calls ++ first it reads the volatile variable value (assume value is 2) since ++ is two operation , before even the first Thread increment the value second Thread reads the volatile variable value (at this point value is still 2) now first 1 incremented value from 2 to 3, and second Thread also does the same as the value was 2 when second the Thread read it. Finally the result would be 3, but expected is 4.

  13. Dharmendra Sahu says:

    Thanks a lot this tutorial.

  14. suresh says:

    nice blog sir…thanks a lot…

  15. Alex says:

    Thank you very much for your site and tutorials!
    You are doing very great job, even after almost 7 years in java development i can find something new in your blog posts!

    Thank you very much and good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages