回答編集履歴
4
2番目の例の回答分も訂正
test
CHANGED
@@ -94,7 +94,7 @@
|
|
94
94
|
|
95
95
|
|
96
96
|
|
97
|
-
上記のようなクラスは「valueを参照したらそれ以前の最後のset結果が得られる」ことを保証できます。しかしもしvolatileが付いていなければ保証がなくなり、スレッドセーフとはいえなくなります。
|
97
|
+
上記のようなクラスは「valueを参照したらそれ以前の最後のset結果が得られる」ことを保証できます。しかしもしvolatileが付いていなければ保証がなくなり、スレッドセーフとはいえなくなります。例えset呼出し後にvalueを参照したとしても、メモリー・フェンスによるアクセス保証がない場合、あるスレッドでvalueを更新後に別のスレッドで更新後の最新の値が読めるという保証がないからです。(コンパイラーの最適化によって過去のvalueのアクセス結果が使いまわされるということもあるかも知れません。)
|
98
98
|
|
99
99
|
|
100
100
|
|
3
訂正:
test
CHANGED
File without changes
|
2
追記2
test
CHANGED
@@ -1,4 +1,26 @@
|
|
1
|
-
追記
|
1
|
+
追記: yohhoyさんご指摘により最初の例の不具合(volatileが抜けている)ことがわかりましたので修正いたしました。失礼しました。
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
追記2: 恥かきついでに自分の考えの間違いの説明を試みます。
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
1. synchronizedでメソッドは排他できる。
|
10
|
+
|
11
|
+
2. countUpが実行の完了時にgetが他のスレッドから呼び出されてもcountUp完了まで待たされる
|
12
|
+
|
13
|
+
3. countUpが実行を完了していればフィールドの値は0->2に書き換わる
|
14
|
+
|
15
|
+
4. その後getが動けば1が読めることはなく、必ず2が読める**(と考えた)**
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
例えば、複数のプロセッサが並行して動作している場合に、プロセッサーごとに独立して動作するキャッシュがあったとすると、例え同一空間上のメモリーを参照したとしても、メモリー・フェンスなしではどのタイミングの値が読めるかの保証がないということだと思います。自分はコンパイラーの最適化によって最新の値を常に参照するかどうかという観点でvolatileを考えていたのですが、メモリー・フェンスの動作について把握できていませんでした。
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
(この解釈にも間違いがあるかも知れません。もしそうならご指摘いただければ非常にありがたいです。)
|
2
24
|
|
3
25
|
|
4
26
|
|
1
訂正
test
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
追記:yohhoyさんご指摘により最初の例の不具合(volatileが抜けている)ことがわかりましたので修正いたしました。失礼しました。
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
|
8
|
+
|
1
9
|
スレッドセーフかどうかは「そのクラス(あるいはそのクラスのインスタンス)」に複数のスレッドから機能にアクセスした際に「矛盾のない結果を保証する」ことを意味します。
|
2
10
|
|
3
11
|
|
@@ -10,7 +18,7 @@
|
|
10
18
|
|
11
19
|
class Counter1 {
|
12
20
|
|
13
|
-
private int count;
|
21
|
+
private volatile int count;
|
14
22
|
|
15
23
|
|
16
24
|
|