2016-10-10 9 views
0

getAndIncrementのcurrentがどのように更新されているかを理解しようとしていますが、ここにそのコードがあります。Java AtomicInteger getAndIncrement()とcompareAndSet

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

私のcompareAndSetは、それが次いで次とレジスタの値を更新し、同じであれば電流値は、レジスタに格納された値と同じであるかどうかを比較することを理解します。

currentの代わりにnextを返さない理由は分かりません。

currentはintとして設定され、currentは参照値ではないため、現在の値が5に初期化されている場合は現在の値が5に初期化されます。または、currentを返すと、currentget()と呼ばれ、レジスタから更新された値を取得します。

+6

[getAndIncrement() '](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndIncrement--)を呼び出すため、ポストインクリメント演算子( 'i ++')と幾分似ています。あなたが記述した動作については、['incrementAndGet()'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet--)があります。これはプリインクリメント演算子( '++ i')に似ています。 – Turing85

+0

私が求めているのは、「現在」がプリミティブとして更新されていることです。「現在」が参照する値のみが更新されています。 –

+0

私はあなたのコメントを完全に理解していません。 Javaは値渡しであるため、 'current'は決して変更されないので、あなたの与えられた例では' 5'が返されます。これはあなたの質問に答えますか? – Turing85

答えて

0

これは並行性を改善するためです。

nextが返された場合は、コードを同期させる必要があります。そうしないと、別のスレッドが値を設定して戻すことができます。

nextを返さないと、実際の変更のみが同期する必要があり、同期の責任と最適化が1か所に必要です。 compareAndSet()。メソッド間で同期を共有する場合、安全な状態の変更を調整する方がはるかに複雑です。

+0

現在は参照ではなくプリミティブな値ですが、現在の呼び出しではreturnの実行時にget()が再度呼び出されますか?ここでは、現在の「参照されている」値が更新されていることしかわかりません。 –

+0

'next'が同期なしで返された場合(およびasiedをオーバーフローさせた場合)、特定の値を返すことができるスレッドが1つしかないと主張できます。なぜなら、1つのスレッドだけがCAS操作を正常に呼び出し、 。 'next'の値は実際の現在の値を返さないかもしれませんが、これは望ましくないかもしれません。 – Turing85

関連する問題