I am doing currently a sample exercise and i found one weird observation that if I replace AutomicInteger with volatile program runs faster. Note : I am only doing read operations.
code:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
AtomicInteger integer = new AtomicInteger(100000000);
// volatile int integer= 100000000;
public static void main(String[] args) {
// We will store the threads so that we can check if they are done
List<Thread> threads = new ArrayList<Thread>();
long start = System.currentTimeMillis();
Main main = new Main();
// We will create 500 threads
for (int i = 0; i < 500; i++) {
Runnable task = new MyRunnable(main.integer);
Thread worker = new Thread(task);
// We can set the name of the thread
worker.setName(String.valueOf(i));
// Start the thread, never call method run() direct
worker.start();
// Remember the thread for later usage
threads.add(worker);
}
int running = 0;
do {
running = 0;
for (Thread thread : threads) {
if (thread.isAlive()) {
running++;
}
}
System.out.println("We have " + running + " running threads. ");
} while (running > 0);
System.out.println("Total Time Required :" +(System.currentTimeMillis()- start));
}
}
MyRunnable class:
import java.util.concurrent.atomic.AtomicInteger;
public class MyRunnable implements Runnable {
private final AtomicInteger countUntil;
MyRunnable(AtomicInteger countUntil) {
this.countUntil = countUntil;
}
@Override
public void run() {
long sum = 0;
for (long i = 1; i < countUntil.intValue(); i++) {
sum += i;
}
System.out.println(sum);
}
}
Time Required for this program to run using AutomicInteger on my machine.
Total Time Required :102169
Total Time Required :90375
Time required for this program to run using volatile on my machine
Total Time Required :66760
Total Time Required :71773
Does this mean volatile is faster than AutomicInteger for read operation also?
This is source code of AtomicInteger. The value is Volatile. So,AtomicInteger uses Volatile inside.
New! Save questions or answers and organize your favorite content. Learn more.
The AtomicInteger class uses CAS (compare-and-swap) low-level CPU operations (no synchronization needed!) They allow you to modify a particular variable only if the present value is equal to something else (and is returned successfully).
Volatile and Atomic are two different concepts. Volatile ensures, that a certain, expected (memory) state is true across different threads, while Atomics ensure that operation on variables are performed atomically.
AtomicInteger
in read context is basically a thin wrapper around volatile int
:
private volatile int value;
public final int get() {
return value;
}
public int intValue() {
return get();
}
Don't expect the wrapper to be faster then the wrapped value taken alone. It can only be as fast as the volatile int
if inlining is employed by the JVM.
And hint: if you are "only doing read operations", this will be even faster:
static final int integer= 100000000;
This question depends on the particular JVM, hardware, and operating system, so the only possible answer is 'maybe'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With