web-dev-qa-db-ja.com

AtomicInteger.incrementAndGet()vs. AtomicInteger.getAndIncrement()

戻り値に関心がない場合、 AtomicInteger.getAndIncrement() メソッドと AtomicInteger.incrementAndGet() メソッドの間に違いがありますか(実際には無関係です)、戻り値が無視される場合

私は、どちらがより慣用的であるか、同期されるCPUキャッシュの負荷を減らすなど、実際には、コインを投げるよりも合理的に使用するものを決定するのに役立つような違いを考えています。

36
hyde

実際の質問への回答が与えられていないため、他の回答(感謝、賛成)とJava規約に基づく私の個人的な意見は次のとおりです。

incrementAndGet()

メソッド名はアクションを説明する動詞で始まる必要があり、ここで意図するアクションはインクリメントのみであるためです。

動詞で始まるのは、一般的なJava規則であり、公式ドキュメントでも説明されています。

「メソッドは動詞で、大文字と小文字が混在し、各内部単語の最初の文字が大文字になっている必要があります。」

25
hyde

コードは基本的に同じなので、問題ではありません。

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

いいえ、違いはありません(戻り値を気にしない場合)。

これらのメソッドのコードは(OpenJDKで)異なりますonlyreturn nextとその他の使用return current

両方とも、まったく同じアルゴリズムでcompareAndSetを内部で使用します。両方ともknow古い値と新しい値の両方が必要です。

8
Joachim Sauer

既存の回答に追加したいだけです。目立たない小さな違いがあります。

この実装 を見ると:

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

唯一の違いは戻り変数であるため、両方の関数の実行はまったく同じです。

4
Iłya Bursov