Atomic Operations without using
java.util.concurrent.atomic package
class Counter {
int count;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class
NonAtomicOperation extends Thread {
private Counter counter;
public
NonAtomicOperation(Counter counter) {
this.counter = counter;
}
public static void main(String[] args) throws
InterruptedException {
Counter counter = new Counter();
NonAtomicOperation thread1 = new
NonAtomicOperation(counter);
NonAtomicOperation thread2 = new
NonAtomicOperation(counter);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
public void run() {
for(int i=0;i<1000;i++)
counter.increment();
}
}
Here, we’ve counter object being shared by two threads
at once. If synchronized not being used then output won’t be 2000
Please note that count++ isn’t 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.
One way to make it right is by using synchronized keyword,
so that one thread at a time access increment() and using join() as well so as
to stop main thread to print the value right away.
Second
Approach
Here is the updated program that will always output
count value as 2000 because AtomicInteger method incrementAndGet() atomically
increments the current value by one.
class Counter {
AtomicInteger count = new
AtomicInteger();
public void increment() {
/* incrementAndGet() atomically
increments the current value by one*/
count.getAndIncrement();
}
public int getCount() {
return count.intValue();
}
}
public class
NonAtomicOperation extends Thread {
private Counter counter;
public
NonAtomicOperation(Counter counter) {
this.counter = counter;
}
public static void main(String[] args) throws
InterruptedException {
Counter counter = new Counter();
NonAtomicOperation thread1 = new NonAtomicOperation(counter);
NonAtomicOperation thread2 = new
NonAtomicOperation(counter);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
public void run() {
for (int i = 0; i < 1000; i++)
counter.increment();
}
}
Output:
2000
Advantages
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.
No comments:
Post a Comment