java.util.concurrent.atomic package:
This package has the following classes. The API says this package as, "A small toolkit of classes that support lock-free thread-safe programming on single variables."
- AtomicBoolean
- AtomicInteger
- AtomicIntegerArray
- AtomicIntegerFieldUpdater<T>
- AtomicLong
- AtomicLongArray
- AtomicLongFieldUpdater<T>
- AtomicMarkableReference<V>
- AtomicReference<V>
- AtomicReferenceArray<E>
- AtomicReferenceFieldUpdater<T,V>
- AtomicStampedReference<V>
Advantages:
Using these classes thread does not require lock on the object. This avoids the waiting time to get the lock. (Locks will be explained further)
Disadvantages:
These classes can be used with only variables, but not with the classes or methods.
I will discuss about the AtomicInteger class here.
AtomicInteger:
AtomicInteger class has some thread safe methods by which it ensures that atomic operations will be executed by a single thread only.
Please see the below program for better understanding.
package thread;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Sivaranjani D
*
*/
public class AtomicIntegerExample {
public static void main(String args[]) {
Incrementer job = new Incrementer();
Thread t1 = new Thread(job);
Thread t2 = new Thread(job);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Normal " + job.getIncerementedNumber());
System.out.println("Atomic " + job.getIncerementedAtomicNumber());
}
}
class Incrementer implements Runnable {
AtomicInteger atomicnumber = new AtomicInteger();
int normalnumber = 0;
public void run() {
for (int i = 0; i < 50; i++) {
increment();
incrementAtomicNumber();
}
}
public int getIncerementedNumber() {
return normalnumber;
}
public void increment() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
normalnumber++;
}
public AtomicInteger getIncerementedAtomicNumber() {
return atomicnumber;
}
public void incrementAtomicNumber() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicnumber.addAndGet(1);
}
}
Explanation:
- Incrementer class implements Runnable and it has 2 fields namely normalnumber of type int and a atomicnumber of type AtomicInteger .
- There are 2 methods namely increment which increments the normalnumber and incrementAtomicNumber which increments the atomicnumber
- And we are calling the above 2 methods in the run method of Incrementer for 50 times .
- We are creating 2 threads in the AtomicIntegerExample class by passing the above Incrementer c lass Object.
- Now both the threads should execute the run method of Incrementer class and loops it for 50 times.
- Since we made t1.join() and t2.join(), main Thread will waits on the both the thread
- After both the threads complets, main thread will print the value.
- The output will be always 50 for the atomicnumber , but when you take the normalnumber it is not. That is because, AtomicInteger does the following 3 tasks (atomic) in a single block but normalnumber does not.
- Read the old value of normalnumber
- Increment the normalnumber
- Reassign the incremented value to normalnumber
No comments:
Post a Comment