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[]相比,它节省了空间,因为它只使用了执行这个魔术所需的一组东西(不安全的类),并使用偏移量来更改它持有的任何一个对象引用。比公认的答案好得多。与原子引用[]相比,它节省了空间-不安全类的一个副本,它可以处理大量对象引用。