2010-09-29 12 views

risposta

6

sembra che sia funzionalmente equivalente a AtomicReference[], occupando però un po 'meno di memoria.

Quindi è utile quando hai bisogno di più di un milione di riferimenti atomici - non riesco a pensare a nessun caso d'uso.

+0

non esattamente corretto - vedere la risposta di fahd per una descrizione. – aperkins

+1

Risposta molto migliore di quella accettata. Salva spazio rispetto a AtomicReference [] - una copia della classe Unsafe, molti riferimenti a oggetti su cui può agire. – themightyjon

1

Potrebbe essere utile se si dispone di un numero elevato di oggetti che vengono aggiornati contemporaneamente, ad esempio in un gioco multiplayer di grandi dimensioni.

Un aggiornamento di riferimento i seguirebbe il modello

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

seconda delle circostanze puo essere più veloce e/o più facile da usare rispetto bloccaggio (synchronized).

8

Se si disponesse di una matrice condivisa di riferimenti a oggetti, si utilizzerà uno AtomicReferenceArray per garantire che l'array non possa essere aggiornato simultaneamente da thread diversi, ovvero un solo elemento può essere aggiornato alla volta.

Tuttavia, in un AtomicReference[] (matrice di AtomicReference) più thread possono ancora aggiornare diversi elementi in modo simulato, poiché l'atomicità è sugli elementi, non sull'array nel suo complesso.

Ulteriori informazioni here.

+1

più thread possono aggiornare contemporaneamente gli elementi AtomicReferenceArray. – irreputable

+0

Non possono. Leggi il link che ho postato. – dogbane

+0

Allora qual è la differenza tra "AtomicReferenceArray' e" AtomicReference [] '? L'implementazione di Sun è di Doug Lea. – dogbane

1

Un possibile caso d'uso sarebbe ConcurrentHashMap che utilizza estensivamente l'array internamente. Le matrici possono essere volatili, ma a livello di elemento la semantica non può essere volatile. è uno dei motivi per cui l'array di automi è nato.

0
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 
+1

Potresti spiegare questo codice? – Twisty