Skip to content

Latest commit

 

History

History
93 lines (67 loc) · 2.29 KB

AtomicIntegerArray.md

File metadata and controls

93 lines (67 loc) · 2.29 KB

無鎖的 Array:AtomicIntegerArray




JDK 提供了原子化處理的陣列結構,有:AtomicIntegerArrayAtomicLongArrayAtomicIntegerReferenceArray


這裡以 AtomicIntegerArray 為例來示範原子陣列使用方式。


AtomicIntegerArray 本質上是對 int[] 封裝,使用 Unsafe 類通過 CAS 控制 int[],保證 Thread Safe。以下列出常用 API:


// 獲得 index 為 i 的元素
public final int get(int i)
// 獲得長度
public final int length()
// 設定 index 為 i 元素的新值,返回舊值
public final int getAndSet(int i, int newVaule)
// CAS 操作,index 為 i 的元素等於 expect 則設置為 update,成功就返回 true
public final boolean compareAndSet(int i, int expect, int update)
// 將 index 為 i 的元素 + 1,並返回舊值
public final int getAndIncrement(int i)
// 將 index 為 i 的元素 - 1,並返回舊值
public final int getAndDecrement(int i)
// 將 index 為 i 的元素 + delta(delta 可以為負值),並返回舊值
public final int getAndAdd(int i, int delta)

使用範例:


public class AtomicIntegerArrayDemo {

    static AtomicIntegerArray arr = new AtomicIntegerArray(10);

    public static class AddTask implements Runnable{

        @Override
        public void run() {
            IntStream.range(0, 10000).forEach(i -> {
                arr.getAndIncrement(i%arr.length());
            });
        }
    }

    public static void main(String[] args) {
        Thread[] ts = new Thread[10];
        IntStream.range(0, 10).forEach(i -> {
            ts[i] = new Thread(new AddTask());
        });
        IntStream.range(0, 10).forEach(i -> {
            ts[i].start();
        });
        IntStream.range(0, 10).forEach(i -> {
            try {
                ts[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(arr);
    }
}

AddTask 對宣告的陣列個元素各加 1000 次,宣告 10 個 Thread,所以是一共加 10000 次。事實上,執行結果也符合我們預期:


[10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000]

AtomicIntegerArray 保證了陣列的 Thread Safe。