volatile
キーワードの背後にある原則を理解しています。 ConcurrentHashMap
源に見たとき、あなたはすべてのノードとの値が値が複数のスレッドからの書き込み/読み出しをすることができますので、理にかなっている、volatile
宣言されていることがわかります、揮発性とArrayBlockingQueueとおそらく他の同時オブジェクト
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
...
}
しかし、ArrayBlockingQueue
ソースに探してそれは複数のスレッドから読み取る/更新されているプレーンな配列です:
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0;
count++;
notEmpty.signal();
}
それはitems[putIndex]
に挿入された値は、配列内の要素が揮発性でないことを提供し、別のスレッドから見えるようになることが保証されている方法(Iその宣言を知っている配列そのものは、要素そのものには何の効果もありません)? 他のスレッドがキャッシュされた配列のコピーを保持できませんでしたか?
おかげ
はい私はそれに気付いたが、私はロックがメモリの障壁として役立つという手がかりはなかった。私は同期があると思ったが、ロックについてはわからなかった。本気ですか? lock()が行うのは、現在のスレッドを排他的な所有者としてマークし、内部状態を設定するためです。私はそれがどのようにメモリの障壁に関連しているのかわかりません – paranoidAndroid
あなたは正しいです、javaの文書では、ロックはsynchronizedと同じメモリ意味を提供しなければならないと言います。だから私はそれが内部的にどのように動作するのだろうか。これらのロックのためのコンパイラによる特定の処理があるかもしれませんか? – paranoidAndroid