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比較是否相等引起...