Я смотрю на реализацию ConcurrentHashMap, и меня что-то смущает.
/* 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;
}
и
/**
* 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();
}
}
и конструктор HashEntry
/**
* 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реализовать
tab[index] = new HashEntry<K,V>(key, hash, first, value);
Я запутался в комментарии HashEntry, так как JSR-133 , когда HashEntry создан, все последние поля будут видны всем другим потокам, значение поле является изменчивым, поэтому я думаю, что оно видимо и другим потокам ???,Другой вопрос, является ли он следующим порядком: ссылка на объект HashEntry может быть назначена вкладке [...] до того, как она будет полностью построена (поэтому в результате другие потоки смогут увидеть эту запись, но значение e.value может быть нулевым)?
Обновление: Я прочитал эту статью, и это хорошо.Но нужно ли мне заботиться о таком случае
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
thread1:
Person p=new Person("name","student");
queue.offer(new Person());
thread2:
Person p = queue.poll();
Есть ли вероятность того, что thread2 получит объект Person с незавершенной конструкцией, такой же, как HashEntry, на вкладке
[index]= новый HashEntry (ключ, хэш, первое, значение);?