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.
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.
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.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
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!
- Alex
nice blog sir…thanks a lot…
- suresh
Thanks a lot this tutorial.
- Dharmendra Sahu
How is atomicity incorporated into the Atomic Integer class? it has to be via locks right ?? Then how is this different from Synchronisation block?
- Sorrowfull Blinger
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.
- Pankaj
I dont think its using locks since synchronization reduces the throughput of the execution and AtomicIntegers are used in lock-free implementation.
- Prashant
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; } }
- sachin
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
- Umesh
what if we have to count the total number of threads and return to the main class? such as 1 + 2 + 3 + 4 +5 = 15.
- Adam
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
- Lalita
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?
- Wells Lee
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.
- IM
I think the count value will be always 8.
- ASHISH JAIN(Technical Consultant)
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.
- Nitin
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.
- Pankaj
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.
- Praneet Pushpal
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.
- Prianc
well said
- craig
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
- Ram
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.
- Swapnil
t1.join();t2.join(); will make run in parallel. you can put sop in code and debug. Thanks Pankaj. great tutorial.
- sachin rane
I think we need better explanation, not just the syntax on how to use AtomicInteger, its available everywhere else on the internet.
- Prashant
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
- ashu
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.
- ashu
Great Job Pankaj . Blogs are very simple and helpful .
- Radhika Sharma
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
- Prakash
String is immutable, so it’s thread-safe. You can use it in the multithreaded environment.
- Pankaj
Can we use instead of AtomicInteger, CountDownLatch for the multithread environment?
- Vimal Panchal
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
- Rakesh Agarwal
IMO the example you took above does not satisfy the issue of atomicity. Though there is no issue with example per se for AtomicInteger but the use case that you have used is not a fit here. Let me know if I am wrong. ~ Salil
- Salil Misra
public class AtomicOperations implements Runnable{ AtomicInteger ai = new AtomicInteger(1); int count = 10; @Override public void run(){ while(ai.get()<= count){ if(ai.get() % 2 == 0 && Thread.currentThread().getName().equals(“Even”)){ System.out.println(Thread.currentThread().getName() + " " + ai.getAndIncrement()); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if(ai.get() % 2 != 0 && Thread.currentThread().getName().equals(“Odd”)){ System.out.println(Thread.currentThread().getName() + " " + ai.getAndIncrement()); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String args[]) throws InterruptedException{ AtomicOperations obj = new AtomicOperations(); Thread t1 = new Thread(obj, “Even”); Thread t2 = new Thread(obj, “Odd”); t1.start(); t2.start(); }
- Rahul
Hi Sir, if we want to run the count by input int x (Scanner). How to pass the int x to another class?
- Ramesh