戻り値に関心がない場合、戻り値を無視すると、メソッドAtomicInteger.getAndIncrement()
とメソッドの間に(実際には無関係でも)違いはありますか?AtomicInteger.incrementAndGet()
私は、どちらがより慣用的であるか、同期されるCPUキャッシュの負荷が少ないか、または実際には、コインを投げるよりも合理的に使用するかを決定するのに役立つものなどの違いを考えています。
戻り値に関心がない場合、戻り値を無視すると、メソッドAtomicInteger.getAndIncrement()
とメソッドの間に(実際には無関係でも)違いはありますか?AtomicInteger.incrementAndGet()
私は、どちらがより慣用的であるか、同期されるCPUキャッシュの負荷が少ないか、または実際には、コインを投げるよりも合理的に使用するかを決定するのに役立つものなどの違いを考えています。
実際の質問に対する答えは与えられていないので、他の答え(感謝、賛成)とJavaの慣習に基づいた私の個人的な意見は次のとおりです。
incrementAndGet()
メソッド名はアクションを説明する動詞で始まる必要があり、ここで意図されているアクションは増分のみであるため、より適切です。
動詞で始まるのは一般的なJavaの慣習であり、公式ドキュメントでも説明されています。
コードは基本的に同じなので、重要ではありません。
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;
}
}
いいえ、違いはありません(戻り値を気にしない場合)。
これらのメソッドのコード(OpenJDK内)は、一方がを使用し、もう一方がを使用するという点でのみ異なります。return next
return current
どちらもcompareAndSet
、まったく同じアルゴリズムで内部的に使用されます。どちらも古い値と新しい値の両方を知る必要があります。
既存の回答に追加したいだけです。目立たない小さな違いがある可能性があります。
この実装を見ると:
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
getAndAddInt
注-両方の関数は、一部を除いてまったく同じ関数を呼び出します。+1
これは、この実装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;
}
}
唯一の違いは戻り変数であるため、両方の関数はまったく同じように実行されます。
ここに例を示します。それがあなたの疑問を解消することを願っています。
私が変数iを持っていると仮定します
AtomicInteger i = new AtomicInteger();
i.getAndIncrement()<==> i ++;
と
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値を出力し、次にインクリメントします。
それで全部です。