Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Почему ConcurrentHashMap#containsValue(), синхр-н, а PriorityBlockingQueue#contain 
:(
    Опции темы
Royan
Дата 29.7.2008, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Задаю вопрос по человечески. Обнаружил, что аналигичные по своему смыслу методы в совершенно разных по смыслу классах реализованы по разному. Пример:

PriorityBlockingQueue.contains(Object):
Код

    public boolean contains(Object o) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return q.contains(o);
        } finally {
            lock.unlock();
        }
    }


ConcurrentHashMap.Segment.containsKey(Object)
     
Код

        boolean containsKey(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))
                        return true;
                    e = e.next;
                }
            }
            return false;
        }


Не вдаваясь в детали реализации сразу видно, что методы не меняющие состояния объекта (containsKey, containsValue, get) в ConcurrentHashMap лишины какой бы то нибыло синхронизации, в то время как в PriorityBlockingQueue аналогичные (не меняющие состояния очереди)  методы (size(), contains()) синхронизированы. Вопрос почему?

Это сообщение отредактировал(а) Royan - 29.7.2008, 15:11


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
Platon
Дата 29.7.2008, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Я думаю, это связано с внутренней реализацией PriorityQueue
Там оочень важна синхронизация, т.к. есть возможность получить ArrayIndexOutOfBoundsException
PM MAIL ICQ   Вверх
yaja
Дата 29.7.2008, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 30.3.2005
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Стоит почитать java-doc к этим классам. ConcurrentHashMap не гарантирует синхронность данных. Если операция чтения совпадает с операцией изменения структуры, то ты эти изменения можешь не увидеть. 
Гарантируется только безопасность работы со структурой из нескольких потоков, чего нету у стандартных HashMap'ов. 
PM MAIL   Вверх
Royan
Дата 29.7.2008, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Цитата(yaja @  29.7.2008,  13:02 Найти цитируемый пост)
ConcurrentHashMap не гарантирует синхронность данных.[...]Гарантируется только безопасность работы со структурой из нескольких потоков

Я не совсем понял, что вы имеете ввиду под синхронностью данных, которая не гарантируется?

Цитата(Platon @  29.7.2008,  12:39 Найти цитируемый пост)
Там оочень важна синхронизация

С доводом не соглашусь, по той причине что и там и там гарантируется безопасность работы в многопоточной среде. Другое дело что для ConcurrentHashMap задокументировано, что операции чтения не синхронизированы: 
Цитата

Retrievals reflect the results of the most recently completed update operations holding upon their onset

К тому же в ConcurrentHashMap были предприняты шаги для того чтобы (даже не знаю как это назвать) увеличить вероятность чтения актуальной информации. О чем это я? Из коментариев к классу java.util.concurrent.ConcurrentHashMap.Segment<K, V>
Цитата

- All (unsynchronized) read operations must first read the "count" field, and should not look at table entries if it is 0.


Поле count объявлено вот так:
Код

transient volatile int count;

Напомню значение модификатора volatile (цитата из JLS3.0)
Цитата

A field may be declared volatile, in which case the Java memory model (§17) ensures that all threads see a consistent value for the variable.

Теперь, внимание вопрос: Почему аналогичным образом не поступить во всех наследниках AbstractQueue?

Это сообщение отредактировал(а) Royan - 29.7.2008, 17:43


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
COVD
Дата 29.7.2008, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

Не вдаваясь в детали реализации сразу видно, что методы не меняющие состояния объекта (containsKey, containsValue, get) в ConcurrentHashMap лишины какой бы то нибыло синхронизации, в то время как в PriorityBlockingQueue аналогичные (не меняющие состояния очереди)  методы (size(), contains()) синхронизированы. Вопрос почему?


Royan, вы сами и ответили на свой вопрос - реализовано по-разному потому, что это "разные по смыслу классы". Один - очередь на основе связанного списка. Другой - мап, т.е. массив. 
PM MAIL   Вверх
ivg
Дата 29.7.2008, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 33
Всего: 81



Короче суть в том, что методы записи ConcurrentHashMap, возможно вкупе с методами чтения, реализованы таким образом, что в любой момент переключения потоков, логическая целостность объекта ConcurrentHashMap, как такового(имеется ввиду непротиворечивость состояния внутренних полей), гарантируется. В отличии от объекта класса PriorityQueue, для которого PriorityBlockingQueue является просто синхронизированной обёрткой.

Это сообщение отредактировал(а) ivg - 29.7.2008, 18:54
PM MAIL   Вверх
Royan
Дата 29.7.2008, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Цитата(COVD @  29.7.2008,  15:30 Найти цитируемый пост)
Один - очередь на основе связанного списка. Другой - мап, т.е. массив. 

Я не нахожу ответа на вопрос, почему если мап то можно кое-что не синхронизировать, а если очередь (не важно на какой основе, ибо все что отростает от AbstractQueue синхронизировано вдоль и поперек) так вот если очередь то, как я говорил, надо ее насквозь залочить.


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
COVD
Дата 29.7.2008, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

Я не нахожу ответа на вопрос, почему если мап то можно кое-что не синхронизировать, а если очередь (не важно на какой основе, ибо все что отростает от AbstractQueue синхронизировано вдоль и поперек) так вот если очередь то, как я говорил, надо ее насквозь залочить.


Ну, наверное, потому, что методы, изменяющие обьект, по-разному меняют структуру. Например, при удалении элемента в мапе значение массива в соответствующем индексе просто становится равно null. А в связанном списке при удалении обнуляются ссылки на следующие элементы. Последствия при итерации возможно будут разные, если не синхронизировать. Или еще что-то. Это следствие оптимизации классов с учетом нюансов структуры. 


PM MAIL   Вверх
Royan
Дата 30.7.2008, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: 3
Всего: 15



Цитата(COVD @  29.7.2008,  17:58 Найти цитируемый пост)
Последствия при итерации возможно будут разные, если не синхронизировать.

Похоже на то 




--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0975 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.