「値」を設定し、すぐに「値」を取得しようとするスレッドが存在する可能性があります。このような場合、デッドロックが発生する可能性はありますか? はいの場合、それを回避する方法は?
2 つのロックが関与しない限り、デッドロックにはなりません (デッドロックの定義を参照)。ただし、getが呼び出されてから setter が呼び出されると、競合状態が発生します。たとえば、2 つのスレッドがgetValue()
値メソッドを順番に呼び出してから、戻ってsetValue(...)
別のメソッドを呼び出すことができます。2 番目のセッターは、もう一方のインクリメントを上書きします。
getValue()
1 に等しいスレッド a 呼び出し
getValue()
1 に等しいスレッド b 呼び出し
- thread-a は値をインクリメントします
- スレッド a は
setValue(...)
、増分値 2 で呼び出します
- thread-b は値をインクリメントします
setValue(...)
増分値 2 でのスレッド b 呼び出し
したがって、答えは 3 になるはずですが、競合状態のために 2 になります。
コードを続けると、get、increment、および set の両方synchronized static void increment()
を行うメソッドが必要になります。はアトミック操作ではないため、そうする必要があります。synchronized
++
public synchronized static int increment() {
value++;
}
AtomicInteger
以上のことから、インクリメントとメモリ同期に関する競合状態を処理する代わりに を使用することを検討する必要があります。