摘要:當前可用的原子數組有和,分別表示整數數組型數組和普通的對象數組。摘自實戰高并發程序設計一書實戰高并發程序設計中的指針類實戰高并發程序設計無鎖的對象引用實戰高并發程序設計帶有時間戳的對象引用
除了提供基本數據類型外,JDK還為我們準備了數組等復合結構。當前可用的原子數組有:AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray,分別表示整數數組、long型數組和普通的對象數組。
這里以AtomicIntegerArray為例,展示原子數組的使用方式。
AtomicIntegerArray本質上是對int[]類型的封裝。使用Unsafe類通過CAS的方式控制int[]在多線程下的安全性。它提供了以下幾個核心API:
//獲得數組第i個下標的元素 public final int get(int i) //獲得數組的長度 public final int length() //將數組第i個下標設置為newValue,并返回舊的值 public final int getAndSet(int i, int newValue) //進行CAS操作,如果第i個下標的元素等于expect,則設置為update,設置成功返回true public final boolean compareAndSet(int i, int expect, int update) //將第i個下標的元素加1 public final int getAndIncrement(int i) //將第i個下標的元素減1 public final int getAndDecrement(int i) //將第i個下標的元素增加delta(delta可以是負數) public final int getAndAdd(int i, int delta)
下面給出一個簡單的示例,展示AtomicIntegerArray使用:
01 public class AtomicIntegerArrayDemo { 02 static AtomicIntegerArray arr = new AtomicIntegerArray(10); 03 public static class AddThread implements Runnable{ 04 public void run(){ 05 for(int k=0;k<10000;k++) 06 arr.getAndIncrement(k%arr.length()); 07 } 08 } 09 public static void main(String[] args) throws InterruptedException { 10 Thread[] ts=new Thread[10]; 11 for(int k=0;k<10;k++){ 12 ts[k]=new Thread(new AddThread()); 13 } 14 for(int k=0;k<10;k++){ts[k].start();} 15 for(int k=0;k<10;k++){ts[k].join();} 16 System.out.println(arr); 17 } 18 }
上述代碼第2行,申明了一個內含10個元素的數組。第3行定義的線程對數組內10個元素進行累加操作,每個元素各加1000次。第11行,開啟10個這樣的線程。因此,可以預測,如果線程安全,數組內10個元素的值必然都是10000。反之,如果線程不安全,則部分或者全部數值會小于10000。
程序的輸出結果如下:
[10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000]
這說明AtomicIntegerArray確實合理地保證了數組的線程安全性。
摘自《實戰Java高并發程序設計》一書
【實戰Java高并發程序設計1】Java中的指針:Unsafe類
【實戰Java高并發程序設計2】無鎖的對象引用:AtomicReference
【實戰Java高并發程序設計 3】帶有時間戳的對象引用:AtomicStampedReference
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65569.html
摘要:在本例中,講述的無鎖來自于并發包我們將這個無鎖的稱為。在這里,我們使用二維數組來表示的內部存儲,如下變量存放所有的內部元素。為什么使用二維數組去實現一個一維的呢這是為了將來進行動態擴展時可以更加方便。 我們已經比較完整得介紹了有關無鎖的概念和使用方法。相對于有鎖的方法,使用無鎖的方式編程更加考驗一個程序員的耐心和智力。但是,無鎖帶來的好處也是顯而易見的,第一,在高并發的情況下,它比有鎖...
摘要:有時候,由于初期考慮不周,或者后期的需求變化,一些普通變量可能也會有線程安全的需求。它可以讓你在不改動或者極少改動原有代碼的基礎上,讓普通的變量也享受操作帶來的線程安全性,這樣你可以修改極少的代碼,來獲得線程安全的保證。 有時候,由于初期考慮不周,或者后期的需求變化,一些普通變量可能也會有線程安全的需求。如果改動不大,我們可以簡單地修改程序中每一個使用或者讀取這個變量的地方。但顯然,這...
摘要:并發包將這種無鎖方案封裝提煉之后,實現了一系列的原子類。無鎖方案相對互斥鎖方案,最大的好處就是性能。作為一條指令,指令本身是能夠保證原子性的。 前面我們多次提到一個累加器的例子,示例代碼如下。在這個例子中,add10K() 這個方法不是線程安全的,問題就出在變量 count 的可見性和 count+=1 的原子性上。可見性問題可以用 volatile 來解決,而原子性問題我們前面一直都...
摘要:實戰高并發程序設計連載中的指針類和非常類似,不同之處就在于是對整數的封裝,而則對應普通的對象引用。這樣,當前線程就無法正確判斷這個對象究竟是否被修改過。摘自實戰高并發程序設計一書 【實戰Java高并發程序設計】連載1–Java中的指針:Unsafe類 AtomicReference和AtomicInteger非常類似,不同之處就在于AtomicInteger是對整數的封裝,而Atomi...
摘要:介紹中無鎖的線程安全整數,一個提供原子操作的的類。在語言中,和操作并不是線程安全的,在使用的時候,不可避免的會用到關鍵字。而則通過一種線程安全的加減操作接口。就是的意思,比較并操作。有個操作數,內存值,舊的預期值,要修改的新值。 【介紹 JAVA 中無鎖的線程安全整數 AtomicInteger,一個提供原子操作的Integer的類。在Java語言中,++i和i++操作并不是線程安全的...
閱讀 2544·2021-10-09 09:44
閱讀 644·2019-08-30 15:44
閱讀 3005·2019-08-29 18:46
閱讀 1142·2019-08-29 18:38
閱讀 565·2019-08-26 10:44
閱讀 2437·2019-08-23 16:07
閱讀 1100·2019-08-23 15:38
閱讀 4114·2019-08-23 14:02