问题描述
/ *专门实现映射方法* /
V get(Object key,int hash){
if(count!= 0){// read-volatile
HashEntry< K,V& e = getFirst(hash);
while(e!= null){
if(e.hash == hash& key.quals(e.key)){
V v = e.value;
if(v!= null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
和
/ **
*读取锁定条目的值字段。如果值
*字段显示为null,则调用。这是可能的,只有当
*编译器碰巧重新排序HashEntry初始化与
*它的表分配,这在内存模型
*是合法的,但不知道永远不会发生。
* /
V readValueUnderLock(HashEntry< K,V> e){
lock();
try {
return e.value;
} finally {
unlock();
}
}
和HashEntry构造函数
/ **
* ConcurrentHashMap列表条目。注意,从不导出
* out作为用户可见的Map.Entry。
*
*因为value字段是volatile,不是final,所以它是合法的wrt
* Java内存模型为一个不同步的阅读器看到null
*而不是初始值通过数据竞赛阅读。虽然导致这种情况的
*重新排序不太可能实际发生
*,但是如果空(预初始化)值为空,则Segment.readValueUnderLock方法用作
*备份在
*中看到一个不同步的访问方法。
* /
static final class HashEntry< K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry< K,V>下一个;
HashEntry(K key,int hash,HashEntry< K,V> next,V value){
this.key = key;
this.hash = hash;
this.next = next;
this.value = value;
}
put implement
tab [index] = new HashEntry< K,V>(key,hash,first,value);
我在HashEntry注释时感到困惑,因为,一旦构造HashEntry,所有最终字段将对所有其他线程可见, value 字段是volatile,所以我认为它可见到其他线程吗? 。其他点是,他说的重排序是:HashEntry对象引用可以分配给tab [...]之前它是完全构造(所以结果是其他线程可以看到这个条目,但e.value可以为null)?
更新:
我阅读了文章,很好。但是我需要关心像这样的情况
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue
thread1:
人p = new Person(name,student);
queue.offer(new Person());
thread2:
Person p = queue.poll();
有可能thread2接收未完成构造的Person对象,就像HashEntry在
解决方案
对于那些对Doug Lea题目,他最近解释了
readValueUnderLock
的原因这是为了回答有问题的人: p>
回应:
它可以全部查看
I'm looking into ConcurrentHashMap implementation and have a thing make me confused.
/* Specialized implementations of map methods */
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
and
/**
* Reads value field of an entry under lock. Called if value
* field ever appears to be null. This is possible only if a
* compiler happens to reorder a HashEntry initialization with
* its table assignment, which is legal under memory model
* but is not known to ever occur.
*/
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
and HashEntry constructor
/**
* ConcurrentHashMap list entry. Note that this is never exported
* out as a user-visible Map.Entry.
*
* Because the value field is volatile, not final, it is legal wrt
* the Java Memory Model for an unsynchronized reader to see null
* instead of initial value when read via a data race. Although a
* reordering leading to this is not likely to ever actually
* occur, the Segment.readValueUnderLock method is used as a
* backup in case a null (pre-initialized) value is ever seen in
* an unsynchronized access method.
*/
static final class HashEntry<K,V> {
final K key;
final int hash;
volatile V value;
final HashEntry<K,V> next;
HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
this.key = key;
this.hash = hash;
this.next = next;
this.value = value;
}
put implement
tab[index] = new HashEntry<K,V>(key, hash, first, value);
I confused at HashEntry comment, as JSR-133, once HashEntry is constructed, all final fields will be visible to all other threads, value field is volatile, so I think it visible to other threads too??? . Other point, is the reorder he said is: HashEntry object reference can be assigned to tab[...] before it is full constructed (so result is other threads can see this entry but e.value can be null) ?
Update:I read this article and it's good. But do I need to care about a case like this
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
thread1:
Person p=new Person("name","student");
queue.offer(new Person());
thread2:
Person p = queue.poll();
Is there a chance that thread2 receive an unfinished-construct Person object just like HashEntry in
解决方案 For those interested in an answer from the Doug Lea on this topic, he recently exlpained the reason for readValueUnderLock
This is in response to someone who had the question:
Response:
It can all be viewed here
这篇关于ConcurrentHashMap重新排序指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!