Sunday, December 13, 2009

Package java.util.concurrent.atomic : JSR 166

Package java.util.concurrent.atomic : JSR 166

Primitive Types



This package helps to write lock free and threadsafe programming. Currently, this packages designed to operate on primitive types int and long. Since int is supported, boolean primitive type also be supported.

java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicBoolean


For instance, I do need to

class Incrementtwo {
private Atomicinteger intNumber = new AtomicInteger(0);
public long next() {
intNumber.getAndIncrement(); //equivalent to i++;
intNumber.incrementAndGet(); //equivalent to ++i;
return intNumber.intValue(); // get int value without any +/- operations
}
}



Similarly, we do have following APIs for AtomicLong and AtomicInteger,

  • to decrement - getAndDecrement() , decrementAndGet()

  • adding/substracting value from delta using APIs - addAndGet(int delta), getAndAdd(int delta)
      if delta is negative then this will do subtraction, there is no separate API for subtraction

  • Plain set APIs - addAndGet(int delta), getAndSet(int newValue)

  • converting to otherprimitive type's value- longValue(),floatValue(), doubleValue(),intValue()

  • Only set value if expected value present- compareAndSet(int expect, int update) , weakCompareAndSet(int expect, int update)
    • weakCompareAndSet performance wise good and possible to face spurious error,
    • this API makes difference with compareAndSet only for Refernces,Updadater.




AtomicBoolean has only set APIs.

Definitely, these APIs are not an alternate for wrapper classes(Integer, Long), since wrapper classes are immutable and has its own hashcode and the equals() logic. Howeever, these Atomic classes are mutable and operates on hashCode and equals of Class.


Array



We have seen how to get, set and increment and decrement values for Integer and Long, how to do it for Arrays of Integer and Long. AtomicIntegerArray AtomicLongArray.

All the above listed APIs available for atomic array class, and almost all the api holds first argument as index of the array.

Reflection



Everything is perfect, I have already a class which cannot be modified by me, because of the fact that comes from our dependency product. How to make sure atomiccally update and get volatile variables. Yes, AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater supports. For instance,



import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntTest {
static class bean
{
volatile int i=0;
}
public static void main(String[] args) {
AtomicIntegerFieldUpdater fu= AtomicIntegerFieldUpdater.newUpdater(bean.class, "i");
bean obj=new bean();
System.out.println(fu.get(obj));
System.out.println(fu.incrementAndGet(obj));
System.out.println(fu.get(obj));
}


Reflection approach may give performance challenges.


Object References:
Is Atomic only support Integer,Long and Boolean ? , No. We can ahieve atomic for float and double by convertint into integer and long using the APIs(floatToIntBits, doubleToLongBits). Eventually, there is a way to deal with object references.

For example, I have send a object reference to an API, where I have to set the different reference to given object reference. In JAVA, we can not change object variable reference until unless the change directly apply to that object variable address. To resolve this issue, we have classes AtomicReference, AtomicReferenceArray, and AtomicReferenceFieldUpdater.

Reference atomicity support extended to intimate that whether this object still alive by marking bit(AtomicMarkableReference) and to hold the version based access to the references by stamping with integer value with reference pair.


import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicStampedReference;

public class AtomicIntTest {
static class bean
{
volatile int i=0;


}
public static void main(String[] args) {

int[] iarray={0,1,2};
bean obj=new bean();
bean obj1=new bean();
bean obj2=new bean();
AtomicStampedReference asr=new AtomicStampedReference(obj,0);
obj1.i=1;

asr.set(obj1,1);
System.out.println(asr.getReference().i); //print i value as 1
asr.set(obj2,2);

System.out.println(asr.get(iarray).i); //print i value as 0

obj2.i=2;
asr.weakCompareAndSet(obj1, obj2, 1, 0);
System.out.println(asr.getReference().i); //print i value as 2

System.out.print(asr.get(iarray).i); //print i value as 2

}
}

No comments:

Post a Comment

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com