8

В JDK 1.6 Дуг Ли использует final, предшествующий полюсу next.Различные `next` записи ConcurrentHashMap в JDK 1.6 и JDK 1.7

static final class HashEntry<K,V> { 
    final K key; 
    final int hash; 
    volatile V value; 
    final HashEntry<K,V> next; 

В то время как в JDK 1.7, то next поле предшествует volatile. Я также замечаю, что в JDK 1.7 метод get использует метод getObjectVolatile для чтения поля value, который имеет семантику летучей нагрузки.

У меня нет никакого смысла, почему Дуг Ли ранее использовал final. Если есть проблемы с правильностью, то как он может заменить его volatile в JDK 1.7 (также JDK 1.8)?

Edit:

В частности, мой вопрос заключается в том, что мы могли бы заменить final с volatile в JDK 1.6 в реализации?

+1

Этот класс не находится в CHM на Java 8. – assylias

+1

Хорошо, если это ваш вопрос, то нет, вы не можете. Причина, по которой был изменен модификатор, заключается в том, что реализация полностью изменилась. Это не изолированное изменение. – RealSkeptic

+1

@RealSkeptic, могли бы вы представить некоторые подробности или статьи для объяснения? Благодарю. –

ответ

2

Для вашего первого вопроса:

У меня нет никакого смысла, почему Doug Lea ранее использует окончательный. Если есть проблемы с правильностью , то как он может заменить его изменчивым в JDK 1.7 (также JDK 1.8)?

Это не вопрос правильности. Обе реализации правильны с точки зрения безопасности потоков. То, что пыталось решить, заключалось в сокращении первоначального следа CHM. В Java 6, чтобы окончание поля next требовало создания объекта, по крайней мере, с помощью держателя места. Это вызвало чрезмерное создание пустого объекта и поэтому было изменено, чтобы предложить семантику создания-когда-то.

В частности, мой вопрос заключается в том, что мы могли бы заменить final изменчивым в реализации JDK 1.6?

Конечно, до тех пор, пока операции продолжают последовательно согласовываться, какими они являются.


Один из Дага Ли комментариев прикосновений этого изменения дизайна

/* 
* ... 
* Historical note: The previous version of this class relied 
* heavily on "final" fields, which avoided some volatile reads at 
* the expense of a large initial footprint. Some remnants of 
* that design (including forced construction of segment 0) exist 
* to ensure serialization compatibility. 
*/ 

Так, чтобы ответить на другой вопрос, который вы, вероятно, имеете, почему final выбрали изначально? Чтобы предотвратить некоторые изменчивые чтения позже.

+0

У меня такая же идея, но я не могу ее подтвердить. Интересно, вы сталкиваетесь с похожими вопросами о Java API, как вы справляетесь с ними? Благодарю. –

0

Это не вопрос замены final на volatile. Подобно RealSkeptic, он был изменен многими другими способами. Целью может быть оптимизация ConcurrentHashMap.remove(). В JDK1.6 список, в котором хранится ведро (объекты, сгруппированные по hashcode), является CopyOnWrite, поэтому внутри remove() часть списка скопирована, только в JDK1.7 указатель next.

 Смежные вопросы

  • Нет связанных вопросов^_^