AtomicInteger.incrementAndGet () vs AtomicInteger.getAndIncrement()

Lorsque la valeur de retour n'est pas intéressante, y a-t-il une différence (même non pertinente dans la pratique) entre AtomicInteger.getAndIncrement() et AtomicInteger.incrementAndGet() méthodes, lorsque la valeur de retour est ignorée?

Je pense à des différences comme celles qui seraient plus idiomatiques, ainsi que celles qui mettraient moins de charge dans les caches CPU synchronisés, ou quoi que ce soit d'autre vraiment, quoi que ce soit pour aider à décider lequel utiliser plus rationnellement que de lancer une pièce de monnaie.

31
demandé sur hyde 2013-02-28 17:56:22

5 réponses

Le code est essentiellement le même, donc peu importe:

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
24
répondu assylias 2013-02-28 13:58:11

Comme aucune réponse à la question réelle n'a été donnée, voici mon opinion personnelle basée sur les autres réponses (merci, upvoted) et la convention Java:

incrementAndGet()

Est meilleur, car les noms de méthode doivent commencer par le verbe décrivant l'action, et l'action prévue ici est d'incrémenter seulement.

Commençant par verbe est la convention Java commune, également décrite par les documents officiels:

"Les méthodes doivent être des verbes, en cas mixte avec la première lettre en minuscules, avec le première lettre de chaque mot en majuscule."

23
répondu hyde 2013-03-01 09:29:22

Non, il n'y a pas de différence (si vous ne vous souciez pas de la valeur de retour).

Le code de ces méthodes (dans le OpenJDK) diffère seulement que l'on utilise return next et l'autre utilise return current.

Les deux utilisent compareAndSet sous le capot avec exactement le même algorithme. Les deux doivent connaître l'ancienne et la nouvelle valeur.

7
répondu Joachim Sauer 2013-02-28 13:58:20

Je veux juste ajouter aux réponses existantes: il pourrait y avoir une très petite différence non perceptible.

Si vous regardez cette mise en œuvre:

public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

Note-les deux fonctions appellent exactement la même fonction getAndAddInt, sauf +1 Partie, ce qui signifie que dans cette implémentation getAndIncrement est plus rapide.

Mais, voici implémentation plus ancienne :

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

La seule différence est la variable de retour, donc les deux fonctions fonctionnent exactement de la même manière.

2
répondu Iłya Bursov 2017-08-30 19:17:25

Ici, je donne un exemple. J'espère que cela effacera votre doute.

Supposons que j'ai une variable i comme

AtomicInteger i = new AtomicInteger ();

Dans ce cas:

I. getAndIncrement () i++;

Et

I. incrementAndGet () ++i;

Veuillez jeter un oeil à ce qui suit les programmes de

public class Test1
{   
    public static void main(String[] args) 
    {               
        AtomicInteger i = new AtomicInteger();
        System.out.println(i.incrementAndGet());  
        System.out.println(i);  

    }

}

**sortie

1 1 ======================================**

public class Test2
{   
    public static void main(String[] args) 
    {               
        AtomicInteger i = new AtomicInteger();
        System.out.println(i.getAndIncrement());  
        System.out.println(i); 

    }

}

**sortie

0 1 -------------**

Commentaire: 1) dans la classe Test1, incrementAndGet () incrémentera d'abord la valeur i, puis imprimera.

2) dans la classe Test2, getAndIncrement () va d'abord Imprimer la valeur i, puis incrémenter.

C'est tout.

-1
répondu Ajju_bhai 2017-06-02 10:47:20