標(biāo)簽:java
原子更新
回顧使用
Aotimic使用(自增桅滋,自減都為原子操作)
private static AtomicLong atomicLong=new AtomicLong(0);
private static Random random=new Random(47);
private static StampedLock stampedLock=new StampedLock();
/**
* Aotimic使用(自增苍鲜,自減都為原子操作)
* 線程操作:將隨機(jī)值賦值給atomicLong
* 多個(gè)線程操作時(shí)承疲,每個(gè)線程都會(huì)以樂觀操作的方式更新值荆针,直到CAS操作成功
*/
private void AtomicDemo(){
for(int i=0;i<10;i++){
new Thread(()->{
long oldValue;
long randomLong;
do{
oldValue=atomicLong.get();
randomLong=random.nextLong();
//不斷循環(huán)鹃两,直到CAS操作成功
}while (!atomicLong.compareAndSet(oldValue,randomLong));
}).start();
}
}
LongAdder,LongAccumulator && DoubleAdder,DoubleAccumulator
大量操作,樂觀鎖需要太多次嘗試,性能下降
LongAdder,LongAccumulator构捡,內(nèi)部維護(hù)多個(gè)累加數(shù)
不同線程更新不同的累加數(shù)独郎,只有需要總值的時(shí)候才累加所有的累加數(shù)
DoubleAdder,DoubleAccumulator同上
private void longAdderTest(){
LongAdder longAdder= new LongAdder();
longAdder.increment();//+1
longAdder.decrement();//-1
longAdder.add(10L);//增加一個(gè)值(非原子操作)
//內(nèi)部多個(gè)變量a1,a2,a3......
LongAccumulator longAccumulator=new LongAccumulator(
//提供一個(gè)函數(shù)(非原子操作)
(a,v)->{return a+v;},
//初始值
0
);
//每次調(diào)用踩麦,其中一個(gè)變量an->(an,10);
longAccumulator.accumulate(10);
//get方法會(huì)統(tǒng)計(jì)所有的變量,輸出a1 op a2 op a3 op......
longAccumulator.get();
}
StampedLock樂觀讀
/**
* StampedLock樂觀讀
*/
private long getCurrentValue(){
//獲得一個(gè)印戳
long stamp=stampedLock.tryOptimisticRead();
long currentValue=atomicLong.get();
//檢驗(yàn)印戳是否可用
if(!stampedLock.validate(stamp)){
//不可用氓癌,某個(gè)線程正在寫,使用悲觀鎖操作
stamp=stampedLock.readLock();
currentValue=atomicLong.get();
stampedLock.unlockRead(stamp);//釋放
}
return currentValue;
}