これを実行すると、64ビットjava8だと思った通りの動作をしますが
32ビットjava8だとたまにこうなります。
Exception in thread "Thread-0" java.lang.RuntimeException: 4294967295
at magicode.check(magicode.java:63)
at magicode.access$100(magicode.java:11)
at magicode$1.run(magicode.java:28)
at java.lang.Thread.run(Thread.java:745)
Finished
Exception in thread "Thread-1" java.lang.RuntimeException: -4294967295
at magicode.check(magicode.java:63)
at magicode.access$100(magicode.java:11)
at magicode$1.run(magicode.java:28)
at java.lang.Thread.run(Thread.java:745)
Finished
1と-1しか入れてないのに例外として
4294967295 や -4294967295 などが返却されてます。
これはなにかというと
4294967295は 「0000 0000 FFFF FFFF」
-4294967295は 「FFFF FFFF 0000 0001」
です。
ちなみに
1は「0000 0000 0000 0001」
-1は「FFFF FFFF FFFF FFFF」
です。
つまり、なにがおこっているのか図で描くとこうなります。
32ビットアーキテクチャで64ビットの領域を扱う場合
32ビットの領域を2つ確保して扱います。
その2つの領域へ値を入れる場合、1回の代入の際に上位ビットと下位ビットを順序よく入れるのですが
タイミングよく2つのスレッドが同時にいれようとするとたまにクロスします。
これがもしも金額計算だったらやばいですよね。
なので、こういったことが起きないように
並行プログラミングする際にはvolatailをつけたりjava.util.concurrent.atomicを使ったり(内部的には同じものらしい)
します。
こういうことをいわゆるスレッドセーフといいます。
まぁ今はあんまり意識しないですかね。