2016-08-09 23 views
5

As Integerクラスも不変クラスであり、不変クラスがスレッドセーフであることがわかっているので、Atomic Integerが必要です。 私は混乱しています。 これは、不変オブジェクトの読み書きがアトミックである必要はないが、原子整数の読み書きはアトミックであるためです。 これは、原子クラスもスレッドセーフであることを意味します。JavaのAtomic IntegerとNormal immutable Integerクラスの違いは何ですか?

+0

どのクラスを使用するか? – user18424

+3

まあ、1つは変更可能で、もう1つは不変です。だから、変更可能な値が必要なとき(他のオプションが存在するとき)、 'AtomicInteger'を使うことができます。あなたは' Integer'を使うことはできません。 –

+1

変更可能な値だけでなく** thread-safe **可変値が必要な場合には、 'AtomicInteger'を使用できます。 – Eduen

答えて

0

可変

int myInt = 3; 

AtomicIntegermyIntに関する検討します。

Integerは、3に関する。

つまり、変数は可変であり、値を変更することができます。値3は整数リテラル、定数、不変式です。

整数はリテラルのオブジェクト表現であり、したがって不変であるため、基本的には読み出すことができます。

AtomicIntegersは、これらの値のコンテナです。あなたはそれを読んで設定することができます。変数に値を代入するのと同じです。しかし、int変数の値を変更することとは異なり、AtomicIntegerの操作はアトミックです。例えば、これは、原子

if(myInt == 3) { 
    myInt++; 
} 

ない

これは不変オブジェクトが定義して、スレッドセーフですが、変更可能なオブジェクトあまりにもスレッドセーフすることができ、原子

AtomicInteger myInt = new AtomicInteger(3); 

//atomic 
myInt.compareAndSet(3, 4); 
+0

この回答には一般的な要点が含まれているようですが、 'AtomicInteger'は' int'変数を参照することができないので、最初の3行の例はちょっと混乱します。 – Kayaman

+0

申し訳ありませんが、私はネイティブスピーカーではない、私は "java参照"として参照する意味はありませんが、 "牛乳は羊を参照して牛を参照して"の意味でより多くの "refer"は正しい単語ではない場合は、 "関連する"より良いだろうか? –

+0

はい、かなり明確です。 – Kayaman

2

です。

これは、Atomic...クラスの目的(AtomicIntegerAtomicBoolean、など)です。

さまざまな...get...および...set...のメソッドは、スレッドセーフなアクセスとオブジェクトの突然変異を許可します。

当然のことながら、クラスはjava.util.concurrentパッケージで宣言されています。

あなただけjava.util.concurrent.atomicパッケージのAPIを参照する必要があります。

単一の変数に対するロックフリーでスレッドセーフなプログラミングをサポートするクラスの小規模なツールキット。通常の整数はスレッドセーフではありませんが

+0

原子クラスは、不変のラッパークラスよりも優れたパフォーマンスを持つはずです。 – user18424

+3

@ user18424同じ目的でそれらを実際に使用することはできないので、間違っていると思います。これら2つのクラス間のパフォーマンスを論理的に比較する方法はありません。 – Kayaman

+0

@ user18424本当にありません。シングルスレッドのコンテキストでは、実際には 'Number'sに固執したいと思っています。それはすべて用途に依存します。 – Mena

0

のAtomicIntegerは、(実際には、は、java.util.concurrent.atomicパッケージからすべてのクラスはスレッドセーフです)、スレッドセーフです。

マルチスレッド環境でInteger変数を使用している場合(スレッドセーフにする)には、「同期」キーワード&が必要です'&' volatile 'キーワードは、スレッド整数型整数として扱われます。また

、私は同じ対象に、以下の役に立つチュートリアルをお勧めします: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html

+0

通常のIntegerクラスはスレッドセーフでもありません – user18424

+0

Normal Integerは、 'synchronized'および 'volatile'キーワードとともに使用する場合にのみスレッドセーフです。 – developer

+0

@developer Integerは不変であり、したがってデフォルトではスレッドセーフであり、同期化または揮発性は必要ありません。しかし、不変性の欠点は、価値が決して変わることができないということです。値を変更する必要がある場合は、AtomicIntegerや他のメソッドやvolatile/synchronizedキーワードを使用してください。 – puhlen

2

のAtomicIntegerは、マルチスレッド環境で使用されます。 http://tutorials.jenkov.com/java-concurrency/compare-and-swap.html

「アトミック」パッケージの詳細については、Oracleのドキュメントの下に参照してください1つのスレッドのみがint変数を更新できることを確認する必要がある場合に使用します。その利点は、値を変更する操作がスレッドセーフな方法で実行されるため、外部同期が必要ないことです。

はfollowindコードを考えてみましょう:

private int count; 

public int updateCounter() { 
    return ++count; 
} 

複数のスレッドがupdateCounterメソッドを呼び出したい場合、それはそれらのいくつかは同じ値を受け取ることになる可能性があります。 ++カウント操作がアトミックではないのは、1つの操作だけでなく、3つの操作から成っている理由です。read count, add 1 to it's value and write it back to it。複数の呼び出しスレッドは、その変数が変更されていないものとして最新の値を参照できます。

上記のコードは、これを交換する必要があります

private AtomicInteger count = new AtomicInteger(0); 
public int updateCounter() { 
    return count.incrementAndGet(); 
} 

incrementAndGet方法がアトミック格納された値をインクリメントし、それが外部synchonizationを用いることなく、値のリターンが保証されます。

値が変更されない場合は、AtomicIntegerを使用する必要はありません。intを使用するだけで十分です。

関連する問題