日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AtomicIntegerArray类详解

發布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AtomicIntegerArray类详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

java.util.concurrent.atomic.AtomicIntegerArray類提供了可以以原子方式讀取和寫入的底層int數組的操作,還包含高級原子操作。 AtomicIntegerArray支持對底層int數組變量的原子操作。 它具有獲取和設置方法,如在變量上的讀取和寫入。 也就是說,一個集合與同一變量上的任何后續get相關聯。 原子compareAndSet方法也具有這些內存一致性功能。

序號方法描述
1public int addAndGet(int i, int delta)原子地將給定的值添加到索引i的元素。
2public boolean compareAndSet(int i, int expect, int update)如果當前值==期望值,則將位置i處的元素原子設置為給定的更新值。
3public int decrementAndGet(int i)索引i處的元素原子并自減1。
4public int get(int i)獲取位置i的當前值。
5public int getAndAdd(int i, int delta)原子地將給定的值添加到索引i的元素。
6public int getAndDecrement(int i)索引i處的元素原子并自減1,并返回舊值。
7public int getAndIncrement(int i)將位置i處的元素原子設置為給定值,并返回舊值。
8public int getAndSet(int i, int newValue)將位置i處的元素原子設置為給定值,并返回舊值。
9public int incrementAndGet(int i)在索引i處以原子方式自增元素。
10public void lazySet(int i, int newValue)最終將位置i處的元素設置為給定值。
11public int length()返回數組的長度。
12public void set(int i, int newValue)將位置i處的元素設置為給定值。
13public String toString()返回數組的當前值的String表示形式。
14public boolean weakCompareAndSet(int i, int expect, int update)如果當前值==期望值,則將位置i處的元素原子設置為給定的更新值。

實例

package main.java.study;

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicIntegerArrayTest {

?? ?static class Increment implements Runnable {

?? ??? ?public void run() {
?? ??? ??? ?for (int i = 0; i < atomicIntegerArray.length(); i++) {
?? ??? ??? ??? ?int add = atomicIntegerArray.incrementAndGet(i);
?? ??? ??? ??? ?System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: " + add);
?? ??? ??? ?}
?? ??? ?}
?? ?}

?? ?static class Compare implements Runnable {

?? ??? ?public void run() {
?? ??? ??? ?for (int i = 0; i < atomicIntegerArray.length(); i++) {
?? ??? ??? ??? ?boolean swapped = atomicIntegerArray.compareAndSet(i, 2, 3);
?? ??? ??? ??? ?if (swapped) {
?? ??? ??? ??? ??? ?System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: 3");
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}

?? ?private static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

?? ?public static void main(String[] args) throws InterruptedException {
?? ??? ?for (int i = 0; i < atomicIntegerArray.length(); i++) {
?? ??? ??? ?atomicIntegerArray.set(i, 1);
?? ??? ?}

?? ??? ?Thread t1 = new Thread(new Increment());
?? ??? ?Thread t2 = new Thread(new Compare());
?? ??? ?t1.start();
?? ??? ?t2.start();

?? ??? ?t1.join();
?? ??? ?t2.join();

?? ??? ?System.out.println("Values: ");
?? ??? ?for (int i = 0; i < atomicIntegerArray.length(); i++) {
?? ??? ??? ?System.out.print(atomicIntegerArray.get(i) + " ");
?? ??? ?}

?? ?}

}

?

?

結果

Thread 11, index 0, value: 3
Thread 10, index 0, value: 2
Thread 10, index 1, value: 2
Thread 10, index 2, value: 2
Thread 10, index 3, value: 2
Thread 10, index 4, value: 2
Thread 10, index 5, value: 2
Thread 10, index 6, value: 2
Thread 10, index 7, value: 2
Thread 10, index 8, value: 2
Thread 10, index 9, value: 2
Values:
3 2 2 2 2 2 2 2 2 2

源碼

AtomicIntegerArray 的public方法主要是call以下方法

public class AtomicIntegerArray implements java.io.Serializable {
??? private static final long serialVersionUID = 2862133569453604235L;

??? private static final Unsafe unsafe = Unsafe.getUnsafe();

? //獲取數組起始位置的偏移量
??? private static final int base = unsafe.arrayBaseOffset(int[].class);
??? private static final int shift;
??? private final int[] array;

??? static {

??????? //獲取數據元素的大小(size),int類型的是 4
??????? int scale = unsafe.arrayIndexScale(int[].class);
??????? if ((scale & (scale - 1)) != 0)
??????????? throw new Error("data type scale not a power of two");

????? //numberOfLeadingZeros:返回無符號整型i的最高非零位前面的0的個數,int類型(4)的前置0個數為29

???? //下面表達式返回位移量,用于計算下標。用于<<操作符,表示乘以2^shift????? 2^2=4
??????? shift = 31 - Integer.numberOfLeadingZeros(scale);
??? }

??? private long checkedByteOffset(int i) {
??????? if (i < 0 || i >= array.length)
??????????? throw new IndexOutOfBoundsException("index " + i);

??????? return byteOffset(i);
??? }

? //計算第i個元素的偏移量.

??? private static long byteOffset(int i) {
??????? return ((long) i << shift) + base;
??? }


??? public AtomicIntegerArray(int length) {
??????? array = new int[length];
??? }

??? public AtomicIntegerArray(int[] array) {
??????? // Visibility guaranteed by final field guarantees
??????? this.array = array.clone();
??? }


??? public final int get(int i) {
??????? return getRaw(checkedByteOffset(i));
??? }

??? private int getRaw(long offset) {
??????? return unsafe.getIntVolatile(array, offset);
??? }


??? public final void set(int i, int newValue) {
??????? unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
??? }

??? public final void lazySet(int i, int newValue) {
??????? unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
??? }

}

數組在內存中是連續內存,如下圖:

012…………n-1

?

Java規定數組中的元素都是相同類型,因此數組中的每個元素的內存大小是相同的,也就是說,只要知道數組的起始位置,我們就可以算出指定下標的數組元素的內存位置

pos = base(起始位置) + i(下標) * size(類型大小)

?

總結

以上是生活随笔為你收集整理的AtomicIntegerArray类详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。