2012-03-12 6 views
2

私は、このシングルステートメントでの同期?

public class NumberClass{ 
    int number; 

    public int getNumber() { 
     return number; 
    } 
    ... 
} 

と複数のスレッドがこのメソッドにアクセスするように一つだけの文を持っているgetterメソッドを持っている私は、このメソッドを同期しなければならないのか、それが唯一の文を持っているので、それが必要でない場合は?

答えて

7

私はこの[取得]メソッドを同期させる必要がありますか、それとも1つのステートメントしか持たないので不要ですか?

1つ以上のステートメントとは関係ありません。値が別のスレッドで更新されているかどうか、すべてのスレッドが一貫した値を参照するかどうかによって異なります。

numberフィールドがthread1で更新された場合、更新の同期方法に応じてthread2が元の値または新しい値のいずれかを取得することがあります。値を適切に公開するには、setメソッドとgetメソッドの両方に​​が必要です。

あなたはちょうどそのvolatileがうまくいくか、確実に複数のスレッド間で値を共有するためにAtomicIntegerを使用することがより適切かもしれないものとしてnumberフィールドをマーキングint値を共有しようとしている場合。

private volatile int number; 

または使用:

private AtomicInteger number = new AtomicInteger(); 
+0

私は同様の質問を同期[ここ]に関連しています(https://stackoverflow.com/questions/47783712/do-not-share-same-socket-between-two-threads-at-the-same-time /)ここで私はソケットオブジェクトの同期を使用していますが、私は同期を完全に取り除くことができるかどうかを確認しようとしていますか?あなたが手伝ってくれるかどうかを知りたい。 – john

+0

彼は@DavidSchwartzをやった。コメントに彼の質問へのリンクがあります。 – Gray

4

はい、そのステートメントを同期させるためには良い考えかもしれません。その理由は、各スレッドが、仕様に応じて、に、それ自身のバージョンの変数をキャッシュすることが許可されているからです。それを実証するために、this answerを見てください。

volatile int number; 
  • またはjava.util.concurrentパッケージからAtomicIntegerを使用する:

    AtomicInteger number; 
    
  • その他のオプションは

    • 変数は揮発性にするためにありますサイドノートとして0

      numberは、タイプlongであったとしても変数のが(一つのスレッドが読み取りの中央における変数の値を書き換えることができる)原子されているだろう読んでいない場合。 Java言語仕様のChapter 17.7: Non-atomic Treatment of double and longを参照してください。

    1

    メモリバリアが必要な場合や、他のスレッドで「正しい」値(つまり、numberに明示的に割り当てられている値)が表示されない場合があります。

    は、この問題を解決finalまたはvolatile部材としてnumberを宣言する、または​​ブロックからそれにアクセスします。

    文の数は、他の回答に反して、です。アトミック性は必要ありません(単一のステートメントなので)​​を使用するのはおそらく過剰です。値が変更された場合はvolatileを使用し、そうでない場合はfinalを使用してください。原子的に動作するようにする必要がある文が複数ある場合は、​​が唯一のオプションです。

    関連する問題