Java 原子引用阵列有什么用?

Java 原子引用阵列有什么用?,java,concurrency,Java,Concurrency,什么时候使用原子引用阵列是个好主意?请举例说明。看起来它在功能上等同于AtomicReference[],但占用的内存稍少一些 因此,当您需要超过一百万个原子引用时,它会很有用—想不出任何用例。如果您有大量对象同时更新,例如在大型多人游戏中,它可能会很有用 参考i的更新将遵循该模式 boolean success = false; while (!success) { E previous = atomicReferenceArray.get(i); E next = ... /

什么时候使用原子引用阵列是个好主意?请举例说明。

看起来它在功能上等同于
AtomicReference[]
,但占用的内存稍少一些


因此,当您需要超过一百万个原子引用时,它会很有用—想不出任何用例。

如果您有大量对象同时更新,例如在大型多人游戏中,它可能会很有用

参考
i
的更新将遵循该模式

boolean success = false;
while (!success)
{
    E previous = atomicReferenceArray.get(i);
    E next = ... // compute updated object
    success = atomicReferenceArray.compareAndSet(i, previous, next);
}

根据具体情况,这可能比锁定更快和/或更容易使用(
synchronized
)。

如果您有一个共享的对象引用数组,然后您将使用
原子引用阵列
来确保数组不能由不同的线程同时更新,即一次只能更新一个元素

但是,在
AtomicReference[]
(AtomicReference的数组)中,多个线程仍然可以模拟地更新不同的元素,因为原子性在元素上,而不是整个数组上


更多信息。

一个可能的用例是ConcurrentHashMap,它在内部广泛使用数组。数组可以是易失性的,但在每元素级别的语义不能是易失性的。这是automic数组出现的原因之一。

import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.atomic.AtomicReferenceArray;

public class AtomicReferenceArrayExample {
    AtomicReferenceArray<String> arr = new AtomicReferenceArray<String>(10);

    public static void main(String... args) {
        new Thread(new AtomicReferenceArrayExample().new AddThread()).start();
        new Thread(new AtomicReferenceArrayExample().new AddThread()).start();
    }

    class AddThread implements Runnable {
        @Override
        public void run() {
            // Sets value at the index 1
            arr.set(0, "A");
            // At index 0, if current reference is "A" then it changes as "B".
            arr.compareAndSet(0, "A", "B");
            // At index 0, if current value is "B", then it is sets as "C".
            arr.weakCompareAndSet(0, "B", "C");
            System.out.println(arr.get(0));
        }
    }

}

//    Result:
//        C
//        C
公共类原子引用ArrayExample{ AtomicReferenceArray arr=新的AtomicReferenceArray(10); 公共静态void main(字符串…参数){ 新线程(新原子引用ArrayExample().new AddThread()).start(); 新线程(新原子引用ArrayExample().new AddThread()).start(); } 类AddThread实现可运行{ @凌驾 公开募捐{ //设置索引1处的值 arr.set(0,“A”); //在索引0处,如果当前引用为“A”,则它将更改为“B”。 arr.compareAndSet(0,“A”,“B”); //在索引0处,如果当前值为“B”,则将其设置为“C”。 arr.weakCompareAndSet(0,“B”,“C”); System.out.println(arr.get(0)); } } } //结果: //C //C
多个线程可以同时更新AtomicReferenceArray元素。它们不能。阅读我发布的链接。那么
AtomicReferenceArray
AtomicReference[]
之间有什么区别?Sun的实现是由Doug Lea实现的,它使用更少的空间,因为
AtomicReferenceArray
中的每个原子引用只占用一个指针。
compareAndSet
操作是在
Unsafe
中通过对指针执行一些特殊的本机操作来完成的。是的,虽然这个答案已被接受,但实际上是不正确的。如果您愿意,您可以检查源代码。正如一些人在这里所说,它是一个对象引用数组,其中任何一个都可以原子地更新。但与数组中的任何其他引用无关。与AtomicReference[]相比,它节省了空间,因为它只使用了执行这个魔术所需的一组东西(不安全的类),并使用偏移量来更改它持有的任何一个对象引用。比公认的答案好得多。与原子引用[]相比,它节省了空间-不安全类的一个副本,它可以处理大量对象引用。