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<Mayfailspuriously
*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原子类,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
 