Javaでintをアトミックかつスレッドセーフに変更するにはどうすればよいですか?
原子的にインクリメント、テスト&セットなど...?
Javaでintをアトミックかつスレッドセーフに変更するにはどうすればよいですか?
原子的にインクリメント、テスト&セットなど...?
AtomicIntegerを使用します。
スレッドセーフは、同期機能を介して実現できます。同期されたメソッドを介して必要な機能を提供するクラスでint(またはそのようなデータ)をラップします。
public class X
{
protected int x;
public synchronized void set( int value )
{
x = value;
}
}
java.util.concurrent.atomicパッケージのクラス(AtomicIntegerやAtomicIntegerArrayなど)を使用することもできます。
synchronized
スレッドレースの影響を解決するために使用できるものがある場合に備えて、この回答の何が問題になっているのかを正確に指摘したかっただけです。
| Thread A | Thread B |
|---------------|------------------|
| read x (x=4) | |
| | read x (x=4) |
| Calculate 4+1 | |
| EAX ← 5 | |
| | Calculate 4+1 |
| | EAX ← 5 |
| Start sync | |
| { | Start sync |
| { x ← 5 | wait |
| { | wait |
| End sync | wait |
| | { |
| | { x ← 5 |
| | { |
| | End sync |
操作の最終結果:
x = 4;
x += 1;
x += 1;
x= 6ではなく5です。
volatile
キーワードにも同じ問題があります。キーワードはvolatile
スレッド効果からあなたを救いません。volatileキーワードは、
厳密に言えば、volatile
メモリ操作が揮発性変数の周りで並べ替えられないようにします。それはあなたがまだ苦しんでいることを意味します:
問題。