J.U.C Atomic array, field atomic operation

Source: Internet
Author: User
Tags cas modifiers throw exception volatile

Here's a look at the atomic array operation and some other atomic operations.

Atomicintegerarray/atomiclongarray/atomicreferencearray's API is similar, select Representative Atomicintegerarray to describe these issues.

intGetintI//get the value of the current positionvoidSetintIintNewValue)//sets the value for a given positionvoidLazyset (intIintnewvalue)intGetandset (intIintnewvalue)BooleanCompareandset (intIintExpectintupdate)BooleanWeakcompareandset (intIintExpectintupdate)intGetandincrement (inti)intGetanddecrement (inti)intGetandadd (intIintDelta)intIncrementandget (inti)intDecremnetandget (inti)intAddandget (intIintDelta

These APIs and Atomicinteger are similar, the difference is that this is an array operation, so multiple index parameters.

Since this is an array operation, there is an array-out-of-bounds problem (Indexoutboundsexception exception), so the int index is checked before the Get/set method is valid. Take a look at the main members of the class first.

    Private Static Final Unsafe unsafe = unsafe.getunsafe ();     Private Static Final int base = unsafe.arraybaseoffset (int[].  Class);     Private Static Final int shift;     Private Final int [] array;

Unsafe.getundafe () did not say, CAS operation without him;

Base: Gets the base address of the array through unsafe;

Shift: The offset of each element in the memory in the array;

Array: the underlying actual operation arrays;

  Static {        int scale = Unsafe.arrayindexscale (int[]. ) Class);          The size of the array element must be 2^x        size if (Scale & (scale-1))! =0            )throwNew Error ("Data type scale not a power of");         =- Integer.numberofleadingzeros (scale);   Bit offset for array element    }

Array index Check:

   Private LongCheckedbyteoffset (inti) {if(I < 0 | | I >=array.length)//index is out of bounds. Throw ExceptionThrow NewIndexoutofboundsexception ("index" +i); returnByteoffset (i); }    Private Static LongByteoffset (inti) {//Gets the memory location of the specified index element (base + offset)return((Long) I << shift) +Base; }

Index check when Set/get:

 Public Final int get (int  i) {        return  getraw (Checkedbyteoffset (i));    }  Public Final void Set (intint  newvalue) {        unsafe.putintvolatile (array, Checkedbyteoffset (i), newvalue);    }

<******************************************************** Field ************************************************ >

atomicintegerfieldupdater<t>/atomiclongfieldupdater<t>/atomicreferencefieldupdate<t,v>

The above three are the values of the field based on the reflected atom update.

The corresponding API is also relatively simple, but there are some constraints.

    1. The field must be of type volatile!
    2. The description type (modifier public/protected/default/private) of a field acts on the caller's relationship to the operand. That is, the caller is able to manipulate the object field directly, then the atomic Operation certificate can be reflected. The private Type field, which the caller cannot access, updates the variable, protected the type variable member, and, when the operand is an instance of the caller class or a subclass, can be accessed, atomically updating the protected member.
    3. Can only be an instance variable, not a class variable, that is, the static keyword cannot be added.
    4. You can only modify variables, and you cannot use the final variable, because the final semantics are not modifiable. In fact, final semantics and volatile are conflicting, and these two keywords cannot exist simultaneously
    5. For Atomicintegerfieldupdater and Atomiclongfieldupdater only the Int/long type field can be modified, its wrapper type (Integer/long) cannot be modified. If you want to modify the wrapper type, you need to use atomicreferencefieldupdater.

Take Atomicintegerfieldupdater as an example:

 Public static <U> atomicintegerfieldupdater<u> newupdater (class<u> tclass, String fieldName) {        returnnew atomicintegerfieldupdaterimpl<u>(Tclass, FieldName, Reflection.getcallerclass ());    }

Atomicintegerfieldupdater is an abstract class that obtains its implementation class instance through the static Newupdater () method, with the arguments being the operand class object, and its variable member name:

 Public Abstract class  atomicintegerfieldupdater<t>privatestaticclassextends Atomicintegerfieldupdater<t>

The abstract method of Atomicintegerfieldupdater is defined as follows:

     Public Abstract BooleanCompareandset (T obj,intExpectintupdate);  Public Abstract BooleanWeakcompareandset (T obj,intExpectintupdate);  Public Abstract voidSet (T obj,intnewvalue);  Public Abstract voidLazyset (T obj,intnewvalue);  Public Abstract intGet (T obj);

Take a look at the inside of its implementation class:

        Private Final Long Offset ;//memory offsets        for member variables Private Final class<t> Tclass;//The Class object        of the Operation object privatefinal class Cclass;  Caller Class object

In the case of member update access, there must be a so-called access check, the above points to explain:

Sun.reflect.misc.ReflectUtil.ensureMemberAccess (//Determination of access rights for member variables (exclude private)
Caller, tclass, NULL, modifiers);
Sun.reflect.misc.ReflectUtil.checkPackageAccess (Tclass); Package access rights


Class Fieldt =Field.gettype (); if(Fieldt! =int.class) Throw NewIllegalArgumentException ("must be integer type"); The type of the variable member must be intif(!Modifier.isvolatile (modifiers))//variable members must be keyword volatile decorated. Throw NewIllegalArgumentException ("must be volatile type"); This. Cclass = (modifier.isprotected (modifiers) &&//1. When the member is protected, assignment Cclass = Caller (Assignment caller class object) 2: not P When rotected, the assignment cclass = null.Caller! = Tclass)? Caller:NULL;

Private void Fullcheck (T obj) {            if (!tclass.isinstance (obj))  // Operation object Not newupdate () incoming                  thrownew  classcastexception ();             if null)  //  cclass is null, so do not further check, direct release,                ensureprotectedaccess (obj);        }

When the variable is proteced decorated:

 Private voidensureprotectedaccess (T obj) {if(cclass.isinstance (obj)) {//When the object to which the atomic operation obj is an instance or subclass of the caller class, release, run atomic operation, otherwise throw. return; }            Throw NewRuntimeException (NewIllegalaccessexception ("Class" +Cclass.getname ()+ "Can not access a protected member of class" +Tclass.getname ()+ "Using an instance of" +Obj.getclass (). GetName ()); }

The Atomicmarkablereference class describes a <object, boolean> pair, that can be atomically modified by an Object or Boolean value, This data structure is useful in some caches or in the Chapter table description. This structure can effectively improve throughput when a single or simultaneous modification of the Object/boolean is possible.

Private Static classPair<t> {        FinalT Reference; Final BooleanMark; PrivatePair (T Reference,BooleanMark) {             This. Reference =reference;  This. Mark =Mark; }        Static<T> pair<t> of (T reference,BooleanMark) {            return NewPair<t>(reference, Mark); }    }Private volatilePair<v> pair;

Take a look at its CAS operations:

  Public BooleanCompareandset (v expectedreference, v newreference, BooleanExpectedmark,BooleanNewMark) {Pair<V> current =pair; returnexpectedreference= = Current.reference &&//in expectreference = = Current. Ref && Expectmark = = Current.mark and the new value pair has either or two not equal to the current value, only updatesExpectedmark= = Current.mark &&((newreference= = Current.reference &&NewMark= = Current.mark) | |Caspair (Current, Pair.of (Newreference, NewMark))); }

The Atomicstampedreference class maintains an object reference with an integer "flag" that can be updated with an atomic method. In contrast to the pair<object of the atomicmarkablereference class, Boolean>,atomicstampedreference maintains a similar <object, The integer> data structure is actually a concurrent count of object references .

 Private Static classPair<t> {        FinalT Reference; Final intStamp; PrivatePair (T Reference,intstamp) {             This. Reference =reference;  This. Stamp =Stamp; }        Static<T> pair<t> of (T reference,intstamp) {            return NewPair<t>(reference, stamp); }    }    Private volatilePair<v> pair;
   Public BooleanCompareandset (v expectedreference, v newreference, intExpectedstamp,intNewstamp) {Pair<V> current =pair; returnexpectedreference= = Current.reference &&Expectedstamp= = Current.stamp &&((newreference= = Current.reference &&Newstamp= = Current.stamp) | |Caspair (Current, Pair.of (Newreference, Newstamp))); }

Both are useful in solving the problem of CAs "ABA".

Reference: http://www.blogjava.net/xylz/archive/2010/07/02/325079.html

J.U.C Atomic array, field atomic operation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.