AtomicLong與LongAdder的區別

2022-08-27 22:36:19 字數 2203 閱讀 7011

atomiclong的原理

atomiclong是通過依靠底層的cas來保障原子性的更新資料,在要新增或者減少的時候,會使用死迴圈不斷地cas到特定的值,從而達到更新資料的目的。

longadder的原理

longadder是在atomiclong的基礎上將單點更新壓力分散到各個節點,在低併發的時候通過對八色的直接更新可以很好的保障和atomiclong的效能基本保持一致,而在高併發的時候通過分散提高了效能。缺點就是longadder在統計的時候如果有併發更新,可能導致統計的資料有誤差。

public class longadder extends striped64 implements serializable

longadder繼承了striped64類,來實現累加功能的,它是實現高併發累加的工具類; 

striped64的設計核心思路就是通過內部的分散計算來避免競爭。 

striped64內部包含乙個base和乙個cell cells陣列,又叫hash表。 

沒有競爭的情況下,要累加的數通過cas累加到base上;如果有競爭的話,會將要累加的數累加到cells陣列中的某個cell元素裡面。所以整個striped64的值為sum=base+∑[0~n]cells。

striped64內部三個重要的成員變數:

/*** 存放cell的hash表,大小為2的冪。

*/transient volatile cell cells;

/*** 基礎值,

* 1. 在沒有競爭時會更新這個值;

* 2. 在cells初始化的過程中,cells處於不可用的狀態,這時候也會嘗試將通過cas操作值累加到base。

*/transient volatile long base;

/*** 自旋鎖,通過cas操作加鎖,用於保護建立或者擴充套件cell表。

*/transient volatile int cellsbusy;

成員變數cells

cells陣列是longadder高效能實現的必殺器: 

atomicinteger只有乙個value,所有執行緒累加都要通過cas競爭value這乙個變數,高併發下執行緒爭用非常嚴重; 

而longadder則有兩個值用於累加,乙個是base,它的作用類似於atomicinteger裡面的value,在沒有競爭的情況不會用到cells陣列,它為null,這時使用base做累加,有了競爭後cells陣列就上場了,第一次初始化長度為2,以後每次擴容都是變為原來的兩倍,直到cells陣列的長度大於等於當前伺服器cpu的數量為止就不在擴容(想下為什麼到超過cpu數量的時候就不再擴容);每個執行緒會通過執行緒對cells[threadlocalrandomprobe%cells.length]位置的cell物件中的value做累加,這樣相當於將執行緒繫結到了cells中的某個cell物件上;

成員變數cellsbusy

cellsbusy,它有兩個值0 或1,它的作用是當要修改cells陣列時加鎖,防止多執行緒同時修改cells陣列,0為無鎖,1為加鎖,加鎖的狀況有三種 

1. cells陣列初始化的時候; 

2. cells陣列擴容的時候; 

3. 如果cells陣列中某個元素為null,給這個位置建立新的cell物件的時候;

成員變數base

它有兩個作用: 

1. 在開始沒有競爭的情況下,將累加值累加到base 

2. 在cells初始化的過程中,cells不可用,這時會嘗試將值累加到base上;

cell內部類

//為提高效能,使用註解@sun.misc.contended,用來避免偽共享,

@sun.misc.contended static final class cell

//使用unsafe類的cas來更新value值

final boolean cas(long cmp, long val)

private static final sun.misc.unsafe unsafe;

//value在cell類中儲存位置的偏移量;

private static final long valueoffset;

//這個靜態方法用於獲取偏移量

static catch (exception e) }}

這個類很簡單,final型別,內部有乙個value值,使用cas來更新它的值;cell類唯一需要注意的地方就是cell類的註解@sun.misc.contended。

AtomicLong和LongAdder的區別

最近在看到不少框架裡面使用到了longadder這個類,而並非atomiclong,很是困惑,於是專門看了longadder的原始碼,總結一下這兩個的區別。就像我們所知道的那樣,atomiclong的原理是依靠底層的cas來保障原子性的更新資料,在要新增或者減少的時候,會使用死迴圈不斷地cas到特定...

AtomicLong和LongAdder的區別

atomiclong和longadder的區別 最近在看到不少框架裡面使用到了longadder這個類,而並非atomiclong,很是困惑,於是專門看了longadder的原始碼,總結一下這兩個的區別。就像我們所知道的那樣,atomiclong的原理是依靠底層的cas來保障原子性的更新資料,在要新...

java 中Long與long引起的bug

long md 123456l linkedlistlist new linkedlist list.add 123456l listiteratorit list.listiterator while it.hasnext 中乙個隱藏了很長時間有bug今天找到了。問題出在了long比較是否相等引起...