Java concurrency之AtomicLongArray原子类_动力节点Java学院整理
AtomicLongArray介绍和函数列表
AtomicLongArray函数列表
//创建给定长度的新AtomicLongArray。 AtomicLongArray(intlength) //创建与给定数组具有相同长度的新AtomicLongArray,并从给定数组复制其所有元素。 AtomicLongArray(long[]array) //以原子方式将给定值添加到索引i的元素。 longaddAndGet(inti,longdelta) //如果当前值==预期值,则以原子方式将该值设置为给定的更新值。 booleancompareAndSet(inti,longexpect,longupdate) //以原子方式将索引i的元素减1。 longdecrementAndGet(inti) //获取位置i的当前值。 longget(inti) //以原子方式将给定值与索引i的元素相加。 longgetAndAdd(inti,longdelta) //以原子方式将索引i的元素减1。 longgetAndDecrement(inti) //以原子方式将索引i的元素加1。 longgetAndIncrement(inti) //以原子方式将位置i的元素设置为给定值,并返回旧值。 longgetAndSet(inti,longnewValue) //以原子方式将索引i的元素加1。 longincrementAndGet(inti) //最终将位置i的元素设置为给定值。 voidlazySet(inti,longnewValue) //返回该数组的长度。 intlength() //将位置i的元素设置为给定值。 voidset(inti,longnewValue) //返回数组当前值的字符串表示形式。 StringtoString() //如果当前值==预期值,则以原子方式将该值设置为给定的更新值。 booleanweakCompareAndSet(inti,longexpect,longupdate)
AtomicLongArray源码分析(基于JDK1.7.0_40)
AtomicLongArray的完整源码
/* *ORACLEPROPRIETARY/CONFIDENTIAL.Useissubjecttolicenseterms. * * * * * * * * * * * * * * * * * * * * */ /* * * * * * *WrittenbyDougLeawithassistancefrommembersofJCPJSR- *ExpertGroupandreleasedtothepublicdomain,asexplainedat *http://creativecommons.org/publicdomain/zero/./ */ packagejava.util.concurrent.atomic; importsun.misc.Unsafe; importjava.util.*; /** *A{@codelong}arrayinwhichelementsmaybeupdatedatomically. *Seethe{@linkjava.util.concurrent.atomic}packagespecification *fordescriptionofthepropertiesofatomicvariables. *@since. *@authorDougLea */ publicclassAtomicLongArrayimplementsjava.io.Serializable{ privatestaticfinallongserialVersionUID=-2308431214976778248L; privatestaticfinalUnsafeunsafe=Unsafe.getUnsafe(); privatestaticfinalintbase=unsafe.arrayBaseOffset(long[].class); privatestaticfinalintshift; privatefinallong[]array; static{ intscale=unsafe.arrayIndexScale(long[].class); if((scale&(scale-))!=) thrownewError("datatypescalenotapoweroftwo"); shift=-Integer.numberOfLeadingZeros(scale); } privatelongcheckedByteOffset(inti){ if(i<||i>=array.length) thrownewIndexOutOfBoundsException("index"+i); returnbyteOffset(i); } privatestaticlongbyteOffset(inti){ return((long)i<May failspuriously *anddoesnotprovideorderingguarantees,soisonlyrarelyan *appropriatealternativeto{@codecompareAndSet}. * *@paramitheindex *@paramexpecttheexpectedvalue *@paramupdatethenewvalue *@returntrueifsuccessful. */ publicfinalbooleanweakCompareAndSet(inti,longexpect,longupdate){ returncompareAndSet(i,expect,update); } /** *Atomicallyincrementsbyonetheelementatindex{@codei}. * *@paramitheindex *@returnthepreviousvalue */ publicfinallonggetAndIncrement(inti){ returngetAndAdd(i,1); } /** *Atomicallydecrementsbyonetheelementatindex{@codei}. * *@paramitheindex *@returnthepreviousvalue */ publicfinallonggetAndDecrement(inti){ returngetAndAdd(i,-1); } /** *Atomicallyaddsthegivenvaluetotheelementatindex{@codei}. * *@paramitheindex *@paramdeltathevaluetoadd *@returnthepreviousvalue */ publicfinallonggetAndAdd(inti,longdelta){ longoffset=checkedByteOffset(i); while(true){ longcurrent=getRaw(offset); if(compareAndSetRaw(offset,current,current+delta)) returncurrent; } } /** *Atomicallyincrementsbyonetheelementatindex{@codei}. * *@paramitheindex *@returntheupdatedvalue */ publicfinallongincrementAndGet(inti){ returnaddAndGet(i,1); } /** *Atomicallydecrementsbyonetheelementatindex{@codei}. * *@paramitheindex *@returntheupdatedvalue */ publicfinallongdecrementAndGet(inti){ returnaddAndGet(i,-1); } /** *Atomicallyaddsthegivenvaluetotheelementatindex{@codei}. * *@paramitheindex *@paramdeltathevaluetoadd *@returntheupdatedvalue */ publiclongaddAndGet(inti,longdelta){ longoffset=checkedByteOffset(i); while(true){ longcurrent=getRaw(offset); longnext=current+delta; if(compareAndSetRaw(offset,current,next)) returnnext; } } /** *ReturnstheStringrepresentationofthecurrentvaluesofarray. *@returntheStringrepresentationofthecurrentvaluesofarray */ publicStringtoString(){ intiMax=array.length-1; if(iMax==-1) return"[]"; StringBuilderb=newStringBuilder(); b.append('['); for(inti=0;;i++){ b.append(getRaw(byteOffset(i))); if(i==iMax) returnb.append(']').toString(); b.append(',').append(''); } } }
AtomicLongArray的代码很简单,下面仅以incrementAndGet()为例,对AtomicLong的原理进行说明。
incrementAndGet()源码如下:
publicfinallongincrementAndGet(inti){ returnaddAndGet(i,1); }
说明:incrementAndGet()的作用是以原子方式将long数组的索引i的元素加1,并返回加1之后的值。
addAndGet()源码如下:
publiclongaddAndGet(inti,longdelta){ //检查数组是否越界 longoffset=checkedByteOffset(i); while(true){ //获取long型数组的索引offset的原始值 longcurrent=getRaw(offset); //修改long型值 longnext=current+delta; //通过CAS更新long型数组的索引offset的值。 if(compareAndSetRaw(offset,current,next)) returnnext; } }
说明:addAndGet()首先检查数组是否越界。如果没有越界的话,则先获取数组索引i的值;然后通过CAS函数更新i的值。
getRaw()源码如下:
privatelonggetRaw(longoffset){ returnunsafe.getLongVolatile(array,offset); }
说明:unsafe是通过Unsafe.getUnsafe()返回的一个Unsafe对象。通过Unsafe的CAS函数对long型数组的元素进行原子操作。如compareAndSetRaw()就是调用Unsafe的CAS函数,它的源码如下:
privatebooleancompareAndSetRaw(longoffset,longexpect,longupdate){ returnunsafe.compareAndSwapLong(array,offset,expect,update); }
AtomicLongArray示例
//LongArrayTest.java的源码 importjava.util.concurrent.atomic.AtomicLongArray; publicclassLongArrayTest{ publicstaticvoidmain(String[]args){ //新建AtomicLongArray对象 long[]arrLong=newlong[]{10,20,30,40,50}; AtomicLongArrayala=newAtomicLongArray(arrLong); ala.set(0,100); for(inti=0,len=ala.length();i运行结果:
get(0):100 get(1):20 get(2):30 get(3):40 get(4):50 getAndDecrement(0):100 decrementAndGet(1):19 getAndIncrement(2):30 incrementAndGet(3):41 addAndGet(100):199 getAndAdd(100):19 compareAndSet():true get(2):1000以上所述是小编给大家介绍的Javaconcurrency之AtomicLongArray原子类,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!