AtomicInteger.incrementAndGet() против AtomicInteger.getAndIncrement()
Когда возвращаемое значение не представляет интереса, существует ли какая-либо (даже неуместная на практике) разница между AtomicInteger.getAndIncrement()
и AtomicInteger.incrementAndGet()
, когда возвращаемое значение игнорируется?
Я думаю о различиях, которые были бы более идиоматичными, а также уменьшали бы нагрузку на тайники CPU, синхронизированные или что-то еще, что-либо, чтобы помочь решить, какой из них использовать более рационально, чем бросать монету.
Ответы
Ответ 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, а затем увеличит его.
Что все.