2012-07-15 1 views
1

Supposons que vous avez la classe suivanteAtomicReference Utilisation

public class AccessStatistics { 
    private final int noPages, noErrors; 
    public AccessStatistics(int noPages, int noErrors) { 
    this.noPages = noPages; 
    this.noErrors = noErrors; 
    } 
    public int getNoPages() { return noPages; } 
    public int getNoErrors() { return noErrors; } 
} 

et vous exécutez le code suivant

private AtomicReference<AccessStatistics> stats = 
    new AtomicReference<AccessStatistics>(new AccessStatistics(0, 0)); 

public void incrementPageCount(boolean wasError) { 
    AccessStatistics prev, newValue; 
    do { 
    prev = stats.get(); 
    int noPages = prev.getNoPages() + 1; 
    int noErrors = prev.getNoErrors; 
    if (wasError) { 
     noErrors++; 
    } 
    newValue = new AccessStatistics(noPages, noErrors); 
    } while (!stats.compareAndSet(prev, newValue)); 
} 

Au cours des deux dernières lignes

newValue = new AccessStatistics(noPages, noErrors); 
while (!stats.compareAndSet(prev, newValue)) 

Est-ce que cela signifie que les nouveaux AccessStatistics créés instance a la même référence que l'instance AccessStatistics actuelle. Comment est-ce possible ? Quelqu'un peut-il l'expliquer? Merci beaucoup.

Répondre

3

stats.compareAndSet(prev, newValue) échouera et retournera faux si la référence actuelle détenue par stats n'est pas prev.

En règle générale, dans un environnement multi-thread, il est très possible que entre prev = stats.get(); et stats.compareAndSet(prev, newValue); un autre thread aurait modifié la référence détenue par stats.

stats.compareAndSet(prev, newValue); dit vraiment:

  • si stats détient encore une référence à prev, comme il était de 5 lignes avant, le mettre à jour pour tenir une référence à newValue
  • si toutefois un autre thread a déjà changé la référence détenu par stats depuis que j'ai vérifié il y a 5 lignes, jeter mon calcul et boucle pour recalculer un nouveau newValue.
+0

Je trouve aussi la réponse en Java Spec aide doc. merci beaucoup –

0

L'objet nouvellement créé est, bien, nouveau. Après la ligne qu'elle est créée, la seule chose qui fait référence à c'est newValue. Rien d'autre ne pourrait - comment le pourrait-il? Le compareAndSet() définit que si rien n'a d'autre dans l'intervalle fixé à une troisième valeur, en plus de l'ancienne connaissance sur prev et la nouvelle que vous avez fait newValue.

+0

Bonne réponse. Merci encore. –

Questions connexes