What is Atomic Operation in java?
Atomic means each action take place in one step without interruption
or we can justify that operation is performed as a single unit of work without
the possibility of interference from other operations.
An Atomic operation can't stop in the middle, either it happened
completely or doesn't happen at all. No side effects of an atomic operation is
visible until the action/operation is complete.
According to java language specification, it guarantees that
·
Reads and writes are atomic for
reference variables and for most primitive variables (for all primitive data
types except long and double).
The operation like below is not an atomic operation:-
int i++;
The upper operation is having 3 steps to complete.
1).
Reading the current value of i;
2).
Incrementing the current value
of i;
3).
Writing the modified value of
i;
Example of non thread safe code in java:-
package com.gaurav.java.atomictest;
public class Counter {
private
int incrementCounter;
/*
* This method is not a thread safe method
because ++ is not an atomic
* operation
*/
public
int getIncrementCounter() {
return
incrementCounter++;
}
}
In the above example, inside the Counter class
the getIncrementCounter() method is not
a thread safe operation because ++(increment operator) is not atomic operation
and I mentioned earlier that this can be broken down into three different
steps. So if multiple threads call this getIncrementCounter() method
simultaneously then each of these
three operation may overlap with each other.
For example while thread 1 is
updating value , thread 2 reads and but still gets old
value, which eventually let thread 2 override thread 1 increment and one
count is lost because multiple threads are
working concurrently.
Writing thread safe code in java for above
scenario's
There are many ways to make the above code as thread
safe in Java:
First
Approach
With the use of synchronized keyword in Java by providing locking to the getIncrementCounter() method,
we can assure that only one thread can execute it at a time which removes
possibility of coinciding or overlapping.
package com.gaurav.java.atomictest;
public class
SynchronizeCounter {
private
int incrementCounter;
/*
This method is thread safe because of locking provided by synchronization */
public
synchronized int getIncrementCounter() {
return
incrementCounter++;
}
}
Second
Approach
With the use of Atomic
Integer which is available in java.util.concurrent.atomic package with jdk1.5
api, which helps to make this ++ operation atomic and since atomic operations
are thread-safe and saves cost of external synchronization.
package com.gaurav.java.atomictest;
import java.util.concurrent.atomic.AtomicInteger;
public class
AutomicIntegerCounter {
AtomicInteger atomicCounterIncrement = new
AtomicInteger(0);
/*
*
This method is thread safe because the counter is incremented
*
automatically using the AtomicInteger class methods
*/
public int
getCountIncrementAutomatically() {
return atomicCounterIncrement.incrementAndGet();
}
}
Facts about thread-safety
- Immutable objects are by default thread-safe because there state can not be changed once created.
- Read only or Final variables are useful in writing of thread safe programs.
- With the use of already available thread safe classes like-StringBuffer, HashTable, Vector e.t.c
- With the use of local variables because each thread has there own copy of local variables.
- By minimizing sharing of objects between multiple thread we can also avaiod the issue of thread safely.
- Volatile keyword in Java can also be used to instruct thread not to cache variables and read from main memory and can also instruct JVM not to reorder or optimize code from threading perspective.
No comments:
Post a Comment