7

私はこれを知っていると思いますが、確認したいと思います。

明らかに、同期は他のスレッドがそれにアクセスするのをブロックしますが、次のような非常に多くの例が見られます

   public synchronized void setValue(int value)
   {
       balance=value;
   }

メソッドが上記のように1行しか実行しない場合、同期する意味がないと私は考えています。

ありがとう

4

4 に答える 4

17

メソッドが上記のように1行しか実行しない場合、同期する意味がないと私は考えています。

いいえ。あなたは、同期は原子性のみを意味すると信じているようです。

しかし、実際にはそれ以上のものを提供します。特に、次のことを保証します。

  • 原子性、これは 1 行の代入には役に立ちません (以下のボーダーの場合を除く)
  • 視認性
  • 並べ替えを防止
  • 相互排除: 同じモニターで同期された 2 つのメソッドを同時に実行することはできません

あなたの例では、同期されていないため、スレッドがメソッドを呼び出し、balanceその後別のスレッドが読み取った場合、その 2 番目のスレッドが更新された値を参照するという保証はありません。

両端で可視性を確保する必要があることに注意してください。書き込みと読み取りは、同じモニターで同期する必要があります。そのため、ゲッターgetBalanceも同期化する必要があります。

境界ケース: double および long 割り当ては、アトミックであるとは限りません。以下のような 1 行の例でも、synchronized キーワードがないと、1 つのスレッドが double の最初の 32 ビットを更新し、別のスレッドが最後の 32 ビットを更新して、新しい混合バランス変数を作成する可能性があります。

public synchronized void setValue(double value) {
    balance = value;
}
于 2013-01-09T18:20:33.650 に答える
2

このメソッドにアクセスする他のスレッドをブロックするだけでなく、同じロック(ここではインスタンス)を持つブロックまたはメソッドにアクセスする他のスレッドをブロックします。

重要なのは、別の同期されたメソッドが長い場合、このメソッドが同時に実行されないことが保証されるということです。

balanceこれは、他のメソッドが実行中に変更されない変数に依存している場合に重要です。

于 2013-01-09T18:19:19.607 に答える
1

同期メソッドは2つのことを行います。

  • 複数のスレッドがそのメソッドを実行することを許可しません
  • スレッドメモリキャッシュを共有メモリと同期します。

あなたの場合、その変数を更新できるのは1つのスレッドだけであり、他のすべてのスレッドは変数内の最新のデータを参照しますbalance

同期がないと、他のスレッドがキャッシュされた値を使用する可能性が高いため、プログラムの実行後balanceに一貫性のない値が取得されます。balance

このプレゼンテーションでは、問題の非常に優れた説明を見つけることができます。

于 2013-01-09T18:22:22.387 に答える
0

複数のスレッドが異なる値で setValue メソッドを呼び出す可能性があります。したがって、あるスレッドの変更が別のスレッドに確実に表示されるようにしたい場合は、メソッドを同期する必要があります。

于 2013-01-09T18:21:31.903 に答える