Подтвердить что ты не робот

AtomicInteger.incrementAndGet() против AtomicInteger.getAndIncrement()

Когда возвращаемое значение не представляет интереса, существует ли какая-либо (даже неуместная на практике) разница между AtomicInteger.getAndIncrement() и AtomicInteger.incrementAndGet(), когда возвращаемое значение игнорируется?

Я думаю о различиях, которые были бы более идиоматичными, а также уменьшали бы нагрузку на тайники CPU, синхронизированные или что-то еще, что-либо, чтобы помочь решить, какой из них использовать более рационально, чем бросать монету.

4b9b3361

Ответ 1

Поскольку ответа на данный вопрос не было, здесь мое личное мнение основывается на других ответах (спасибо, подтверждено) и Java-конвенции:

incrementAndGet()

лучше, потому что имена методов должны начинаться с глагола, описывающего действие, и предполагаемое действие здесь - только для увеличения.

Начиная с глагола является общим соглашением Java, также описанным официальными документами:

Методы должны быть глаголами, в смешанном случае с первой строчной буквой, с первой буквой каждого внутреннего слова, заглавным.

Ответ 2

Код по существу тот же, что и не имеет значения:

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;
    }
}

Ответ 3

Нет, нет никакой разницы (если вы не заботитесь о возвращаемом значении).

Код этих методов (в OpenJDK) отличается только тем, что использует return next, а другой использует return current.

Оба используют compareAndSet под капотом с тем же самым алгоритмом. Оба должны знать как старое, так и новое значение.

Ответ 4

Просто хочу добавить к существующим ответам: может быть очень маленькая не заметная разница.

Если вы посмотрите эту реализацию:

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

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

Примечание. Оба вызова функции выполняют ту же функцию getAndAddInt, за исключением +1 part, что означает, что в этой реализации getAndIncrement выполняется быстрее.

Но вот старая реализация:

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;
    }
}

Единственное различие - это возвращаемая переменная, поэтому обе функции выполняют точно то же самое.

Ответ 5

Здесь я приведу пример. Надеюсь, что это очистит ваши сомнения.

Предположим, что у меня есть переменная я как

AtomicInteger я = новый AtomicInteger();

В этом случае:

i.getAndIncrement() < == > я ++;

И

i.incrementAndGet() < == > ++ i;

Пожалуйста, просмотрите приведенные ниже программы

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

    }

}

** выход

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

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

    }

}

** выход

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

Комментарий: 1) В классе Test1, incrementAndGet() сначала увеличивает значение i, а затем печатает.

2) В классе Test2 getAndIncrement() сначала напечатает значение i, а затем увеличит его.

Что все.