摘要:注意原子數組并不是說可以讓線程以原子方式一次性地操作數組中所有元素的數組。類的方法返回指定類型數組的元素所占用的字節數。,是將轉換為進制,然后從左往右數連續的個數。
本文首發于一世流云的專欄:https://segmentfault.com/blog...一、Atomic數組簡介
Atomic數組,顧名思義,就是能以原子的方式,操作數組中的元素。
JDK提供了三種類型的原子數組:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。
這三種類型大同小異,AtomicIntegerArray對應AtomicInteger,AtomicLongArray對應AtomicLong,AtomicReferenceArray對應AtomicReference。
其實閱讀源碼也可以發現,這些數組原子類與對應的普通原子類相比,只是多了通過索引找到內存中元素地址的操作而已。
注意:原子數組并不是說可以讓線程以原子方式一次性地操作數組中所有元素的數組。
而是指對于數組中的每個元素,可以以原子方式進行操作。
說得簡單點,原子數組類型其實可以看成原子類型組成的數組。
比如:
AtomicIntegerArray array = new AtomicIntegerArray(10); array.getAndIncrement(0); // 將第0個元素原子地增加1
等同于
AtomicInteger[] array = new AtomicInteger[10]; array[0].getAndIncrement(); // 將第0個元素原子地增加1二、AtomicIntegerArray原理
本節將以AtomicIntegerArray為例,介紹下原子數組的原理,AtomicLongArray和AtomicReferenceArray的使用和源碼與AtomicIntegerArray大同小異,讀者可以自己查看Oracle官方文檔和源碼。
AtomicIntegerArray其實和其它原子類區別并不大,只不過構造的時候傳入的是一個int[]數組,然后底層通過Unsafe類操作數組:
可以看到,AtomicIntegerArray提供了兩種構造器,本質都是內部利用array變量保存一個int[]數組引用。
另外,AtomicIntegerArray利用Unsafe類直接操作int[]對象的內存地址,以達到操作數組元素的目的,幾個關鍵的變量解釋如下:
int base = unsafe.arrayBaseOffset(int[].class);
Unsafe類的arraBaseOffset方法:返回指定類型數組的第一個元素地址相對于數組起始地址的偏移值。
int scale = unsafe.arrayIndexScale(int[].class);
Unsafe類的arrayIndexScale方法:返回指定類型數組的元素所占用的字節數。比如int[]數組中的每個int元素占用4個字節,就返回4。
那么,通過base + i * sacle 其實就可以知道 索引i的元素在數組中的內存起始地址。
但是,觀察AtomicIntegerArray的byteOffset方法,是通過i << shift + base 的公式計算元素的起始地址的:
$$ i << shift + base = i * 2^{shift} + base $$
這里,$$ 2^{shift} $$其實就等于scale。
shift = 31 - Integer.numberOfLeadingZeros(scale),Integer.numberOfLeadingZeros(scale)是將scale轉換為2進制,然后從左往右數連續0的個數。
讀者可以自己計算下:
shift = 31 - Integer.numberOfLeadingZeros(4) = 31 - 29 =2
之所以要這么繞一圈,其實是處于性能的考慮,通過移位計算乘法的效率往往更高。
三、AtomicIntegerArray接口聲明文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/76577.html
摘要:整個包,按照功能可以大致劃分如下鎖框架原子類框架同步器框架集合框架執行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據一系列常見的多線程設計模式,設計了并發包,其中包下提供了一系列基礎的鎖工具,用以對等進行補充增強。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發于一世流云專欄:https...
摘要:在并發量較低的環境下,線程沖突的概率比較小,自旋的次數不會很多。比如有三個,每個線程對增加。的核心方法還是通過例子來看假設現在有一個對象,四個線程同時對進行累加操作。 showImg(https://segmentfault.com/img/remote/1460000016012084); 本文首發于一世流云的專欄:https://segmentfault.com/blog... ...
摘要:本身不直接支持指針的操作,所以這也是該類命名為的原因之一。中的許多方法,內部其實都是類在操作。 showImg(https://segmentfault.com/img/remote/1460000016012251); 本文首發于一世流云的專欄:https://segmentfault.com/blog... 一、Unsafe簡介 在正式的開講 juc-atomic框架系列之前,有...
摘要:所謂,就是可以以一種線程安全的方式操作非線程安全對象的某些字段。我們來對上述代碼進行改造賬戶類改造引入通過操作字段調用方,并未做任何改變上述代碼,無論執行多少次,最終結果都是,因為這回是線程安全的。這也是整個包的設計理念之一。 showImg(https://segmentfault.com/img/remote/1460000016012109); 本文首發于一世流云的專欄:http...
摘要:顧名思義,是類型的線程安全原子類,可以在應用程序中以原子的方式更新值。創建對象先來看下對象的創建。也就是說當一個線程修改一個共享變量時,其它線程能立即讀到這個修改的值。 showImg(https://segmentfault.com/img/remote/1460000016012210); 本文首發于一世流云的專欄:https://segmentfault.com/blog... ...
閱讀 3736·2021-11-24 09:39
閱讀 2617·2019-08-30 15:54
閱讀 1159·2019-08-30 13:01
閱讀 3436·2019-08-28 18:30
閱讀 1631·2019-08-26 17:44
閱讀 3598·2019-08-26 11:31
閱讀 2422·2019-08-26 10:40
閱讀 1252·2019-08-26 10:27